探究volatile和synchronized,深入理解多线程安全
2023-09-14 15:12:31
前言
在多线程编程中,volatile和synchronized是两个非常重要的。它们都可以用来保证多线程环境下的数据安全,但它们的工作原理却截然不同。
volatile关键字可以保证变量的可见性,即当一个线程修改了变量的值时,其他线程能够立即看到这个修改。synchronized关键字可以保证变量的原子性,即当一个线程正在访问变量时,其他线程不能同时访问这个变量。
volatile关键字
volatile关键字可以保证变量的可见性。当一个线程修改了volatile变量的值时,其他线程能够立即看到这个修改。这是因为volatile关键字会将变量的值存储在主内存中,而主内存是所有线程共享的。
为了证明volatile关键字的可见性,我们可以编写一个简单的代码示例:
public class VolatileDemo {
private volatile int number = 0;
public void increment() {
number++;
}
public static void main(String[] args) {
VolatileDemo volatileDemo = new VolatileDemo();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
volatileDemo.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
volatileDemo.increment();
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终结果:" + volatileDemo.number);
}
}
在这个示例中,我们创建了一个VolatileDemo对象,并在两个线程中分别调用increment()方法。increment()方法将number变量的值递增1。由于number变量是volatile的,因此两个线程可以看到彼此的修改,最终结果将是20000。
synchronized关键字
synchronized关键字可以保证变量的原子性。当一个线程正在访问synchronized变量时,其他线程不能同时访问这个变量。这是因为synchronized关键字会在访问变量的线程上加锁,当其他线程试图访问这个变量时,将被阻塞,直到持有锁的线程释放锁。
为了证明synchronized关键字的原子性,我们可以编写一个简单的代码示例:
public class SynchronizedDemo {
private int number = 0;
public synchronized void increment() {
number++;
}
public static void main(String[] args) {
SynchronizedDemo synchronizedDemo = new SynchronizedDemo();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
synchronizedDemo.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 10000; i++) {
synchronizedDemo.increment();
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终结果:" + synchronizedDemo.number);
}
}
在这个示例中,我们创建了一个SynchronizedDemo对象,并在两个线程中分别调用increment()方法。increment()方法将number变量的值递增1。由于number变量是synchronized的,因此两个线程只能交替访问这个变量,最终结果将是20000。
比较
volatile和synchronized关键字都是用来保证多线程环境下的数据安全,但它们的工作原理不同。volatile关键字可以保证变量的可见性,而synchronized关键字可以保证变量的原子性。
volatile关键字比较轻量级,不会导致线程阻塞,而synchronized关键字比较重量级,会导致线程阻塞。因此,在实际应用中,我们应该根据具体情况选择合适的关键字。
总结
volatile和synchronized关键字是Java多线程编程中非常重要的两个关键字。它们都可以用来保证多线程环境下的数据安全,但它们的工作原理不同。volatile关键字可以保证变量的可见性,而synchronized关键字可以保证变量的原子性。在实际应用中,我们应该根据具体情况选择合适的关键字。