本文共 1849 字,大约阅读时间需要 6 分钟。
在学习多线程编程时,同步和易失性是两个关键概念。前篇已经探讨了同步的骚操作,本篇将深入分析同步状语从句,了解其与易失性之间的区别,易失性的使用条件,以及虚拟机层面的一些实现细节。
synchronized
保证了可见性和原子性。volatile
仅保证可见性,不具备原子性。volatile
修饰的变量后,其他线程可以立即发现新值。synchronized
可能会导致线程阻塞,因为它争夺资源时会让其他线程等待。volatile
不会引起阻塞,因为它不会影响线程的执行流程。synchronized
能保证线程安全,而volatile
不适用于这种场景。volatile
主要用于标记完成或中断等场景,例如资源是否被释放或信号是否正确传递。synchronized
修饰的是方法或代码块,而volatile
修饰的是变量。volatile
修饰的变量不会被重排序,减少了同步有关的复杂性。volatile
变量的写操作总是比后续的读操作先发生。这体现了内存的一致性模型。x + y = k
总是成立,除非这是非多线程环境下的绝对需求。volatile
时不需要额外的锁定机制,因为它不需要保护代码块的可执行性。虚拟机通过以下机制确保易失性变量的一致性:
volatile
修饰的变量时,其修改操作会立即反映到主内存中。以下示例代码展示了volatile
变量作为开关的应用:
public class ValiableTest { public static void main(String[] args) { boolean isRunning = false; Thread t1 = new Thread(() -> { while (isRunning) { System.out.println("运行中......"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }); new Thread(() -> { isRunning = false; System.out.println("下面终止运行"); }).start(); t1.start(); }}
volatile
修饰:如果不使用volatile
,isRunning
变量在多线程环境下可能不会更新,导致程序无法正常终止。volatile
修饰:若isRunning
被volatile
修饰,主线程的修改会及时反映到其他线程,程序才能正常终止。通过对比synchronized
和volatile
的特性,我们可以更好地理解它们各自适用的场景。synchronized
更适合保护共享资源的原子性操作,而volatile
则用以处理快速变更的状态标记,如资源释放或信号传递。在实际编码中,应该根据具体需求选择合适的机制。
转载地址:http://kaxhz.baihongyu.com/