英文:
Thread-safe in Singleton pattern which holder members
问题
以下是翻译好的内容:
我有这个带有单例模式的示例代码:
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("存在 t1,计数为="+Singleton.getInstance().getCount());
});
t1.start();
Thread.sleep(1000); //超时以强制在 t2 之前启动 t1
Thread t2=new Thread(()->{
Singleton.getInstance().setCount(10000);
});
t2.start();
t1.join();
t2.join();
}
}
我有一个问题:在线程 t1 和 t2 中调用的 getCount
和 setCount
方法是线程安全的,是吗?
英文:
I have this sample code with Singleton pattern:
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();
}
}
I have a question: Method getCount
and setCount
which called in two thread t1, t2 is thread-safe, isn't it?
答案1
得分: 0
>Method getCount/setCount 在两个线程 t1、t2 中被调用,是线程安全的,对吗?
如果您的意图是使线程 t1 能够看到由 t2 进行的更改,是的,线程 2 设置的计数将对线程 t1 可见。
这是因为线程 1 每次通过调用 getInstance
获取单例实例,而该方法是同步的。这建立了一个先行发生关系,使线程 2 所做的更改对线程 1 可见。
然而,如果您将代码更改为仅调用一次 getInstance
,然后使用该引用调用 getCount
,那么另一个线程(t2)所做的更改可能对线程 t1 不可见,线程 t1 可能会一直循环。
Singleton s = Singleton.getInstance();
while(s.getCount()==0){
//循环
}
为了使更改得以反映,您需要将 count
声明为易失性(volatile)
private volatile int count;
英文:
>Method getCount/setCount which called in two thread t1, t2 is thread-safe, isn't it?
If you intention is to make the changes made by t2 visible to t1 - yes, the count set by thread 2 will be visible to thread t1.
This is because thread 1 gets the singleton instance every time by calling getInstance
which is a synchronized
method. This establishes a happens-before relationship and the changes made by thread 2 will be visible to thread 1.
However, if you change your code to call getInstance
only once and use that that reference to call getCount
, then the changes made by another thread (t2) may not become visible to thread t1 and it can keep looping.
Singleton s = Singleton.getInstance();
while(s.getCount()==0){
//loop
}
To make the changes get reflected, you have to make count
a volatile
private volatile int count;
专注分享java语言的经验与见解,让所有开发者获益!
评论