文章目录
  1. 1. 饿汉式(线程安全)
  2. 2. 懒汉式(非线程安全)
  3. 3. 测试类

饿汉式(线程安全)

1
2
3
4
5
6
7
8
9
10
package test;

public class Single {
//恶汉式
private static Single single=new Single();
private Single(){}
public static Single getInstance(){
return single;
}
}

懒汉式(非线程安全)

1
2
3
4
5
6
7
8
9
10
11
12
package test;

public class Single2 {
private static Single2 instance;
private Single2(){}
public static Single2 getInstance(){
if(instance==null){//1:读取instance的值
instance=new Single2();//2: 实例化instance
}
return instance;
}
}

对于以上代码注释部分,如果此时有两个线程,线程A执行到1处,读取了instance为null,然后cpu就被线程B抢去了,此时,线程A还没有对instance进行实例化。因此,线程B读取instance时仍然为null,于是,它对instance进行实例化了。然后,cpu就被线程A抢去了。此时,线程A由于已经读取了instance的值并且认为它为null,所以,再次对instance进行实例化。所以,线程A和线程B返回的不是同一个实例。
解决线程安全需要在getInstance方法上加上synchronized修饰。

测试类

1
2
3
4
5
6
7
8
package test;

public class MyThread extends Thread{
@Override
public void run(){
System.out.println(Single2.getInstance().hashCode());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package test;

public class Run {
public static void main(String[] args) {
MyThread t1=new MyThread();
MyThread t2=new MyThread();
MyThread t3=new MyThread();
MyThread t4=new MyThread();
t1.start();
t2.start();
t3.start();
t4.start();
}
}
文章目录
  1. 1. 饿汉式(线程安全)
  2. 2. 懒汉式(非线程安全)
  3. 3. 测试类