Java synchronized 和 volatile 的区别是什么?
Java
中的 synchronized
和 volatile
都涉及到多线程编程,但它们的作用和使用场景略有不同。
synchronized
关键字:
- 作用: 用于实现对共享资源的互斥访问,确保在同一时刻只有一个线程能够访问临界区代码。
- 使用场景: 当多个线程访问共享资源时,使用
synchronized
来保护共享数据的一致性。
代码示例:
public class SynchronizedExample {private int sharedVariable = 0;public synchronized void increment() {sharedVariable++;}public synchronized int getSharedVariable() {return sharedVariable;}
}
在上述示例中,increment
方法和 getSharedVariable
方法都使用了 synchronized
关键字,确保对 sharedVariable
的访问是原子的,从而避免了多线程并发访问时可能出现的数据不一致问题。
volatile
关键字:
- 作用: 保证可见性,防止指令重排序,但不提供原子性。
- 使用场景: 适用于一个线程写,多个线程读的场景,并且对变量的写操作不依赖于当前值。
代码示例:
public class VolatileExample {private volatile int sharedVariable = 0;public void increment() {sharedVariable++;}public int getSharedVariable() {return sharedVariable;}
}
在这个示例中,sharedVariable
声明为 volatile
,这意味着对 sharedVariable
的写操作对其他线程是可见的。然而,需要注意的是,虽然 volatile
提供了可见性,但它不能保证复合操作的原子性。如果 increment
涉及到多步骤的操作,仍然需要使用 synchronized
或其他并发控制机制。
总体来说,synchronized
用于提供原子性和互斥性,而 volatile
主要用于提供可见性。在实际应用中,根据具体的需求和场景,可以灵活地选择使用它们。