繁体   English   中英

持有者成员的 Singleton 模式中的线程安全

[英]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 中调用的方法getCountsetCount是线程安全的,不是吗?

在两个线程 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM