Java中volatile关键字未生效,代码是否存在错误?
问题分析与解决
你的代码核心问题
你的代码里thread1和thread2是两个独立的MutliThreadExample实例,每个实例都有自己的value成员变量。两个线程分别操作各自实例的value,完全不存在变量共享的场景,所以volatile关键字在这里根本发挥不了作用——加不加它,两个线程的操作都互不干扰,输出结果自然一致。
什么场景下volatile才有用
volatile的核心作用是保证共享变量的可见性(一个线程修改变量后,其他线程能立刻看到最新值),同时禁止指令重排序。只有当多个线程同时操作同一个共享变量时,它的效果才会体现出来。
修改后的示例代码
要验证volatile的作用,需要让多个线程操作同一个共享变量,以下是两种可行的修改方式:
方式1:使用static共享变量
public class MutliThreadExample extends Thread{ // 改为static,让所有线程共享这个变量 static volatile int value; public static void main(String[] args) throws InterruptedException { MutliThreadExample thread1 = new MutliThreadExample(); MutliThreadExample thread2 = new MutliThreadExample(); thread1.start(); // 去掉join,让两个线程同时运行 thread2.start(); } @Override public void run() { for (int i = 1; i <= 5; i++) { value = value + 1; System.out.println(value + "-" + Thread.currentThread().getName()); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }
方式2:共用同一个实例
public class MutliThreadExample implements Runnable{ volatile int value; public static void main(String[] args) throws InterruptedException { MutliThreadExample sharedInstance = new MutliThreadExample(); Thread thread1 = new Thread(sharedInstance); Thread thread2 = new Thread(sharedInstance); thread1.start(); thread2.start(); } @Override public void run() { for (int i = 1; i <= 5; i++) { value = value + 1; System.out.println(value + "-" + Thread.currentThread().getName()); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }
补充说明
注意:volatile不能解决原子性问题,比如value = value + 1这个操作是非原子的(包含读取、加1、写入三步),即使加了volatile,也可能出现线程安全问题(比如两个线程同时读取到相同的值,加1后写入导致最终值比预期小)。如果要保证原子性,需要配合synchronized或者使用AtomicInteger类。
内容的提问来源于stack exchange,提问作者shravan
相关产品推荐
相关产品推荐

