Java多线程编程必备volatile与synchronized深入理解攻略
什么是多线程编程
在计算机科学中,多线程是指一个程序中包含了多个执行流,这些执行流可以并行执行。多线程编程可以提升程序的执行效率,提供更好的用户体验。但是,多线程编程也会带来更高的难度,因为多线程程序的行为是不确定的,可能会产生竞态条件和死锁等问题。因此,多线程编程需要程序员具备一定的经验和技巧。
为什么需要volatile关键字
在Java中,如果一个变量被多个线程共享,那么每个线程可以从主存中读取该变量的值,并在自己的工作内存中对该变量进行操作。如果一个线程修改了该变量的值,其他线程不能立即知道该变量的改变。这种情况可能会导致线程之间的数据不一致或者死锁等问题。
为了解决这个问题,Java引入了volatile关键字。volatile关键字用于修饰变量,保证该变量在多个线程之间的可见性。当一个变量被volatile修饰之后,每个线程在修改变量的值时,都会将该变量的最新值写回主内存,并从主内存中读取该变量的值,从而保证所有线程操作的都是同一份数据。
volatile关键字示例
下面的代码展示了如何使用volatile关键字来保证多个线程之间变量的可见性:
public class VolatileDemo {
private volatile int count = 0;
public void increment() {
count++;
}
public int getCount() {
return count;
}
public static void main(String[] args) throws InterruptedException {
final VolatileDemo demo = new VolatileDemo();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000000; i++) {
demo.increment();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000000; i++) {
demo.increment();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Count: " + demo.getCount());
}
}
上面的代码创建了一个VolatileDemo对象,该对象包含了一个volatile修饰的计数器变量count。在main方法中,创建了两个线程t1和t2,每个线程都会对count变量进行10000000次自增操作。在两个线程执行完毕之后,我们输出了count的值。由于count是volatile修饰的,因此该变量在多个线程之间的可见性得到了保证,不会出现线程之间数据不一致的情况。
为什么需要synchronized关键字
在Java中,如果多个线程同时修改同一个变量,那么就有可能出现竞态条件。竞态条件的典型例子是“先检查再执行”,也就是说,多个线程先对共享变量进行检查,然后再对变量进行修改操作。在这种情况下,每个线程的操作都是原子性的,但是由于多个线程同时执行,导致结果出现了问题。
为了解决这个问题,Java引入了synchronized关键字。synchronized关键字用于修饰代码块和方法,保证在同一个时刻只有一个线程可以执行被synchronized修饰的区域。如果有多个线程尝试进入synchronized区域,其他线程只能等待,直到当前线程执行完毕。
synchronized关键字示例
下面的代码展示了如何使用synchronized关键字来保证多个线程之间的同步执行:
public class SynchronizedDemo {
private int count;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
public static void main(String[] args) {
final SynchronizedDemo demo = new SynchronizedDemo();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000000; i++) {
demo.increment();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000000; i++) {
demo.increment();
}
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Count: " + demo.getCount());
}
}
上面的代码创建了一个SynchronizedDemo对象,该对象包含了一个计数器变量count,并使用synchronized修饰increment()方法。在主线程中,创建了两个线程t1和t2,每个线程都会对count变量进行10000000次自增操作。由于increment()方法被synchronized修饰,因此同一时刻只能有一个线程访问该方法,从而保证了多个线程之间的同步执行。最终,我们输出了count变量的值,验证了increment()方法在多线程环境下的正确性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程编程必备volatile与synchronized深入理解 - Python技术站