[英]Thread-safe in Singleton pattern which holder members
我有这个带有 Singleton 模式的示例代码:
class Singleton{
private static Singleton instance;
private int count;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
public int getCount(){return count;}
public void setCount(int count){this.count=count;}
public static void main(String[] args) throws InterruptedException{
Thread t1=new Thread(()->{
while(Singleton.getInstance().getCount()==0){
//loop
}
System.out.println("exist t1 with count="+Singleton.getInstance().getCount());
});
t1.start();
Thread.sleep(1000); //time out to force t1 start before t2
Thread t2=new Thread(()->{
Singleton.getInstance().setCount(10000);
});
t2.start();
t1.join();
t2.join();
}
}
我有一个问题:在两个线程 t1、t2 中调用的方法getCount
和setCount
是线程安全的,不是吗?
在两个线程 t1、t2 中调用的方法 getCount/setCount 是线程安全的,不是吗?
如果您打算使 t2 所做的更改对 t1可见- 是的,线程 2 设置的计数将对线程 t1 可见。
这是因为线程 1 每次都通过调用synchronized
方法getInstance
获取 singleton 实例。 这建立了一个happens-before关系,线程2所做的更改将对线程1可见。
但是,如果您将代码更改为仅调用一次getInstance
并使用该引用来调用getCount
,则另一个线程 (t2) 所做的更改可能对线程 t1 不可见,并且它可以继续循环。
Singleton s = Singleton.getInstance();
while(s.getCount()==0){
//loop
}
要使更改得到反映,您必须将count
设为volatile
private volatile int count;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.