在Java中,使用`synchronized`块来同步对共享变量的访问是一种常见的多线程编程技术。这种方式可以帮助你防止在多个线程同时访问和修改同一资源时产生的数据不一致或竞态条件。
下面是一个使用`synchronized`块来同步变量访问的简单示例。在这个例子中,我们有一个共享的资源(一个整数变量`count`),以及两个线程分别尝试增加这个变量的值。
public class SynchronizedBlockExample {
// 这是一个共享资源
private int count = 0;
// 一个方法,用于在synchronized块中同步对count的访问
public void increment() {
// 使用synchronized块锁定当前对象的监视器
synchronized(this) {
// 在这里,count的访问是同步的
// 只有一个线程可以执行这个块中的代码
count++;
}
// 当线程退出synchronized块时,它会自动释放锁
}
public static void main(String[] args) throws InterruptedException {
SynchronizedBlockExample example = new SynchronizedBlockExample();
// 创建两个线程来增加count的值
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
// 启动线程
thread1.start();
thread2.start();
// 等待线程完成
thread1.join();
thread2.join();
// 输出最终结果
System.out.println("Final count: " + example.count);
}
}
在这个例子中,`increment`方法中的`synchronized(this)`块确保了每次只有一个线程可以执行该块中的代码,从而安全地增加`count`的值。`this`关键字指的是当前`SynchronizedBlockExample`对象的实例,用作同步的锁。你也可以使用其他对象作为锁,但重要的是要确保所有需要同步访问共享资源的线程都使用相同的锁。
注意,虽然`synchronized`块提供了基本的线程同步机制,但在某些情况下,它可能会引入性能瓶颈,因为线程在尝试获取锁时可能会阻塞。因此,在设计多线程程序时,需要仔细考虑何时以及如何使用同步。