该ThreadPool实现是否正确?关于线程可见性的疑问
你的理解部分正确,我们逐一分析:
关于isStopped变量
你担心它的多线程可见性问题,但实际上不需要额外声明为volatile或使用原子变量。原因是:
- 对
isStopped的所有读写操作都被synchronized方法保护:doStop()(写操作)和isStopped()(读操作)都是同步方法。 - 根据Java内存模型,进入
synchronized方法时,线程会从主内存加载变量的最新值;退出同步方法时,线程会把变量的修改同步回主内存。这已经完全保证了isStopped在多线程间的可见性和原子性,额外的volatile是冗余的。
关于thread变量
这里确实存在可见性风险,你的判断是对的,需要优化:
run()方法中this.thread = Thread.currentThread();的赋值操作没有被同步机制保护,而doStop()方法(由其他线程调用)是同步方法,会读取thread变量并调用interrupt()。- 极端情况下,池线程已经设置了
thread变量,但由于没有同步,主线程调用doStop()时可能看不到这个最新值,导致thread为null,进而抛出NullPointerException。 - 解决方法二选一:
- 把
thread声明为volatile,强制变量的读写操作直接与主内存交互,保证可见性; - 在
run()方法中给thread赋值时,加入synchronized(this)块,通过同步机制保证赋值操作的内存可见性。
- 把
额外补充:ThreadPool类的isStopped
当前代码中对这个变量的所有读写都在synchronized方法里,暂时不存在可见性问题,但如果未来扩展代码(比如新增非同步的读取操作),就可能出现问题。如果要更严谨,可以给它加上volatile修饰,或者保持现有同步方式不变。
内容的提问来源于stack exchange,提问作者Siddharth
相关产品推荐
相关产品推荐

