设计模式 - 对于Java多线程synchronized(.class)和valatile的困惑?

查看:285
本文介绍了设计模式 - 对于Java多线程synchronized(.class)和valatile的困惑?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

这是head first 设计模式中单例模式第182页的一段代码

public class Singleton {
    // 为什么要使用volatile关键字?
    private volatile static Singleton uniqueInstance;
    
    private Singleton() {}
    
    public static Singleton getInstance() {
        if (uniqueInstance == null) {
            /* 为什么要使用synchronized (Singleton.class),使用synchronized(this)或者
            synchronized(uniqueInstance)不行吗?而且synchronized(uniqueInstance)的效率更加高?*/
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                 }
            }
        }
        return uniqueInstance;
    }
}

问题一:为什么要使用volatierle关键字?
问题二:为什么要使用synchronized (Singleton.class),使用synchronized(this),或者synchronized(uniqueInstance)不行吗?而且synchronized(uniqueInstance)的效率更加高?


Stackoverflow上面的答案

对于问题一

public class Foo extends Thread {
  private volatile boolean close = false;
  public void run() {
    while(!close) {
      // do work
    }
  }
  public void close() {
    close = true;
    // interrupt here if needed
  }
}

you need volatile because the thread reading close in the while loop is different from the one that calls close(). Without volatile, the thread running the loop may never see the change to close.


对于问题二,作者并没有给出原因,只贴出了代码

static void myMethod() {
  synchronized(MyClass.class) {
    //code
  }
}
is equivalent to

static synchronized void myMethod() {
  //code
}
and

void myMethod() {
  synchronized(this) {
    //code
  }
}
is equivalent to

synchronized void myMethod() {
  //code
}

解决方案

1、volatile保证了uniqueInstance的修改对各个线程的可见性。
2、这是个static方法synchronized(this)肯定是不行的,因为没有this。再说synchronized(uniqueInstance)synchronized是针对对象而言的,对象都是堆里的对象,但是初始化状态下uniqueInstancenull,只是栈里的一个标识,在堆里没有。我试了一下synchronized(null)会报空指针异常。

这篇关于设计模式 - 对于Java多线程synchronized(.class)和valatile的困惑?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆