单例:在虚拟机里保证类对象只有一个。比如:计数器。
1.直接初始化
2.你用我的时候我再初始化:
问题:多线程的时候会出现多个
3.加锁 synchronized
4.加锁加强版
5.防止指令重排序 volatile
1.直接初始化
Public calss Mgr01
{
private static final Mgr01 INSTANCE =new Mgr01();
private Mgr01(){}
public static Mgr01 getInstance(){return INSTANCE;}
public void m(){System.out.println("m");}
public static void main()
{
Mgr01 m1=Mgr01.getInstance();
Mgr01 m2=Mgr01.getInstance();
System.out.println(m1==m2);
}
}
2.你用我的时候我再初始化
问题:多线程的时候会出现多个
Public calss Mgr02
{
private static final Mgr02 INSTANCE;//1.实例变量
private Mgr02(){} //2.构造函数
public static Mgr02 getInstance() //3.得到实例
{
if(INSTANCE==null) //两个线程同时访问,会new两个INSTANCE。
{
INSTANCE=new Mgr02();
}
return INSTANCE;
}
//匿名的线程构造函数
// thread().start();
/*thread(
()->
).start();*/
public void m(){ System.out.println("m");}
public static void main()
{
for(int i=0;i<100;i++)
{
new Thread(()->
System.out.println(Mgr02.getInstance().hashCode())
).start();
}
}
}
3.加锁 synchronized
Public calss Mgr03
{
private static final Mgr03 INSTANCE;
private Mgr03(){}
public static synchronized Mgr03 getInstance() //加锁synchronized
{
if(INSTANCE==null)
{
INSTANCE=new Mgr03();
}
return INSTANCE;
}
public void m(){ System.out.println("m");}
public static void main()
{
for(int i=0;i<100;i++)
{
new Thread(()->
System.out.println(Mgr03.getInstance().hashCode())
).start();
}
}
}
4.加锁加强版
5.防止指令重排序 volatile
Public calss Mgr05
{
private static final Mgr05 INSTANCE;
private Mgr05(){}
public static volatile Mgr05 getInstance() //volatile
{
if(INSTANCE==null) //如果为空
{
// 1.如果两个线程同时运行到此 那么会顺序的运行两次new
synchronized(Mgr05.class)
{
if(INSTANCE==null) //2.所以必须有这句
{
INSTANCE=new Mgr03();
}
}
}
return INSTANCE;
}
public void m(){ System.out.println("m");}
public static void main()
{
for(int i=0;i<100;i++)
{
new Thread(()->
System.out.println(Mgr05.getInstance().hashCode())
).start();
}
}
}