手把手教你理解Volatile关键字

    技术2022-07-11  83

    volatile关键字

    volatile 关键字是java提供的一种轻量级同步机制。他能够保证可见性和有序性,但是不能保证原子性。

    volatile可见性

    可见性表示被这个关键字所修饰的实例,在被修改后,其他的线程均可见。 class MyData { // 如果没有volatile关键字的话,那我们在修改number的时候其他线程是不可知的。 // int number = 0; volatile int number = 0; } public class VolatileLookDemo { public static void main(String[] args) { MyData myData = new MyData(); new Thread(() -> { try { TimeUnit.SECONDS.sleep(2); myData.number = 100; System.out.println(myData.number+"修改数据"); } catch (InterruptedException e) { e.printStackTrace(); } }, "AAA").start(); new Thread(() -> { System.out.println("进入了BBB的线程"); while (myData.number == 0) { // 如果我们线程中number在其他线程被修改了,就会跳出while } System.out.println("它发现number被修改为"+myData.number); System.out.println("BBB线程要出来了"); }, "BBB").start(); } }

    代码说明:

    在MyData类中我们定义了我们定义了number 域。我们可以选择添加volatile和不加volatile关键字的方式进行测试。

    在主线程中我们创建了MyData的实例对象myData。我们新建了两个线程AAA与线程BBB。

    我们可以看到AAA线程对myData的number进行修改。BBB线程负责监听numner是否被修改。

    运行结果说明:

    在number不添加volatile关键字的情况下,我们会发现我们的程序会陷入死循环。原因是:BBB线程监听number,而number在AAA线程中被修改这个事情,BBB线程他并不知道。也就是锁number在AAA线程中的操作是其他线程不可见的,所以while就会一直循环。

    在number添加了volatile关键字的情况下,程序会运行结束。因为此时的number在AAA线程中的修改结果对于其他线程是可见的,那么BBB线程的while监听到number被修改为100,自然跳出了循环。

    总结:

    通过上面的小demo我们可以清晰的发现添加了volatile关键字后,我们的域在不同线程中的操作都是可见的。
    Processed: 0.013, SQL: 9