饿汉式
package Singleton;
// 饿汉式会浪费空间
public class HungryMan {
private HungryMan () {
}
public final static HungryMan HUNGRY_MAN= new HungryMan();
public static HungryMan getHungryMan(){
return HUNGRY_MAN;
}
}
懒汉式
单线程可以,多线程不可以
package Singleton;
public class LazyMan {
private LazyMan(){
}
private static LazyMan lazyMan;
public static LazyMan getInstance(){
if (lazyMan== null){
lazyMan=new LazyMan();
}
return lazyMan;
}
}
所以加一把锁
双层检测锁模式,DCL懒汉式
为了避免指令重排 volatile
package Singleton;
public class LazyMan {
private LazyMan() {
}
private volatile static LazyMan lazyMan;
public static LazyMan getInstance() {
if (lazyMan == null) {
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan();
}
}
}
return lazyMan;
}
}
静态内部类实现
package Singleton;
public class Holder {
private Holder(){
}
public static Holder getInstance(){
return InnerClass.HOLDER;
}
public static class InnerClass{
private final static Holder HOLDER = new Holder();
}
}
反射破坏单例私有
package Singleton;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class LazyMan {
private LazyMan() {
}
private volatile static LazyMan lazyMan;
public static LazyMan getInstance() {
if (lazyMan == null) {
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan(); // 不是原子性操作
}
}
}
return lazyMan;
}
public static void main(String[] args) throws Exception{
LazyMan instance = LazyMan.getInstance();
Constructor<LazyMan> declaredConstructor = null;
declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyMan instance1 = declaredConstructor.newInstance();
System.out.println(instance);
System.out.println(instance1);
}
}
变成三重锁
package Singleton;
import java.lang.reflect.Constructor;
public class LazyMan {
private LazyMan() {
if (lazyMan!=null){
synchronized (LazyMan.class){
throw new RuntimeException("不要试图用反射去破坏");
}
}
}
private volatile static LazyMan lazyMan;
public static LazyMan getInstance() {
if (lazyMan == null) {
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan(); // 不是原子性操作
}
}
}
return lazyMan;
}
public static void main(String[] args) throws Exception{
LazyMan instance = LazyMan.getInstance();
Constructor<LazyMan> declaredConstructor = null;
declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyMan instance1 = declaredConstructor.newInstance();
System.out.println(instance);
System.out.println(instance1);
}
}
如果不用new对象,都用反射 单例又被破坏
public static void main(String[] args) throws Exception{
Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyMan instance = declaredConstructor.newInstance();
LazyMan instance1 = declaredConstructor.newInstance();
System.out.println(instance);
System.out.println(instance1);
}
设置变量判断
package Singleton;
import java.lang.reflect.Constructor;
public class LazyMan {
private static Boolean lixin= false;
private LazyMan() {
if (lixin==false){
lixin=true;
}else{
throw new RuntimeException("不要试图用反射去破坏");
}
}
private volatile static LazyMan lazyMan;
public static LazyMan getInstance() {
if (lazyMan == null) {
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan(); // 不是原子性操作
}
}
}
return lazyMan;
}
public static void main(String[] args) throws Exception{
Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyMan instance = declaredConstructor.newInstance();
LazyMan instance1 = declaredConstructor.newInstance();
System.out.println(instance);
System.out.println(instance1);
}
}
把变量破坏所以最好用枚举
package Singleton;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class LazyMan {
private static Boolean lixin= false;
private LazyMan() {
if (lixin==false){
lixin=true;
}else{
throw new RuntimeException("不要试图用反射去破坏");
}
}
private volatile static LazyMan lazyMan;
public static LazyMan getInstance() {
if (lazyMan == null) {
synchronized (LazyMan.class) {
if (lazyMan == null) {
lazyMan = new LazyMan(); // 不是原子性操作
}
}
}
return lazyMan;
}
public static void main(String[] args) throws Exception{
Field lixin = LazyMan.class.getDeclaredField("lixin");
lixin.setAccessible(true);
Constructor<LazyMan> declaredConstructor = LazyMan.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
LazyMan instance = declaredConstructor.newInstance();
lixin.set(instance,false);
LazyMan instance1 = declaredConstructor.newInstance();
System.out.println(instance);
System.out.println(instance1);
}
}