Java并发编程 - synchronized 的魅力之旅
2023-12-02 10:31:34
引言
各位开发者,欢迎踏上 Java 并发编程之旅的第 53 站。今天,我们将深入探讨 synchronized ,它的魅力在于确保并发环境中的代码执行安全。让我们一起揭开它的奥秘!
目录
- synchronized 的使用方式
- synchronized 的原理
- 线程的等待、中断与唤醒
一、synchronized 的使用方式
synchronized 可以保证在同一个时刻,只有一个线程执行被 synchronized 修饰的代码块或方法。有以下几种使用方式:
1. 修饰方法
public synchronized void someMethod() {
// ...
}
2. 修饰代码块
synchronized (this) {
// ...
}
其中,this
表示当前对象。
二、synchronized 的原理
synchronized 的实现依赖于 Java 对象头中的一个 监视器锁 。当一个线程获取某个对象的监视器锁时,它就获得了该对象的独占访问权,其他线程将被阻塞,直到该锁被释放。
三、线程的等待、中断与唤醒
1. 线程等待
使用 wait()
方法可以使线程进入等待状态,直到监视器锁被释放。
synchronized (this) {
this.wait();
}
2. 线程中断
可以使用 interrupt()
方法中断处于等待状态的线程。
synchronized (this) {
this.wait();
// 如果被中断,执行后续操作
}
3. 线程唤醒
通过 notify()
和 notifyAll()
方法,持有监视器锁的线程可以唤醒一个或所有等待的线程。
synchronized (this) {
this.notify();
}
收获
- 理解 synchronized 的使用方式和原理。
- 掌握线程的等待、中断与唤醒机制。
案例研究
让我们编写一个简单的多线程程序,演示 synchronized 的用法:
public class Counter {
private int count;
public synchronized void increment() {
++count;
}
}
public class Main {
public static void main(String[] args) {
Counter counter = new Counter();
Thread[] threads = new Thread[100];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(() -> {
for (int j = 0; j < 1000; j++) {
counter.increment();
}
});
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
thread.join();
}
System.out.println("Final count: " + counter.count);
}
}
在这个程序中,我们创建了一个 Counter
类,它的 increment()
方法使用 synchronized 关键字进行保护,确保每次只有一个线程可以增加 count
变量。我们创建了 100 个线程,每个线程都执行 1000 次 increment()
操作。通过使用 synchronized,我们保证了 count
变量在并发环境下可以被安全地更新。
总结
Java 的 synchronized 关键字为并发编程提供了强大的保障机制,帮助我们编写出安全可靠的多线程程序。通过理解它的使用方式、原理和线程同步机制,开发者可以充分发挥并发编程的优势,创建出高效且无并发问题的应用程序。