Java多线程同步问题:简单锁与条件变量示例
在Java中,多线程的同步主要通过两种机制实现:简单锁和条件变量。
- 简单锁:Java中的Object类提供了synchronized关键字来声明一个代码块,这个代码块在这个对象的所有实例上都会具有相同的锁。常见的锁对象有Thread.currentThread()。
示例:
public class SimpleLockExample {
private Object lock = new Object();
public synchronized void criticalSection() {
System.out.println("Critical Section: Locking...\n");
// Critical code here
System.out.println("\nCritical Section: Unlocking...\n");
}
public static void main(String[] args) {
SimpleLockExample example = new SimpleLockExample();
Thread thread1 = new Thread(() -> {
try {
example.criticalSection();
} catch (InterruptedException e) {
e.printStackTrace();
}
}));
Thread thread2 = new Thread(() -> {
try {
example.criticalSection();
} catch (InterruptedException e) {
e.printStackTrace();
}
}));
// 启动线程
thread1.start();
thread2.start();
// 等待所有线程执行完毕
while (!thread1.isAlive() && !thread2.isAlive()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("\nProgram finished successfully!\n");
}
}
在这个示例中,我们创建了一个简单锁,它由一个对象实例化。criticalSection()
方法被声明为synchronized,这意味着在同一时间只有一个线程能够访问这个代码块。
条件变量(Condition Variable)用于在满足特定条件后通知其他线程。在这个例子中,并没有直接使用条件变量,但如果需要等待某个条件出现后再执行代码,可以引入Condition对象来实现。
- 条件变量:Java中的 Condition接口提供了wait()和notifyAll()方法,用于实现多线程间的同步。
示例:
import java.util.concurrent.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionVariableExample {
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void criticalSection() {
try {
lock.lock(); // 获取锁
System.out.println("Critical Section: Locking...\n");
// Critical code here
System.out.println("\nCritical Section: Unlocking...\n");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
try {
lock.unlock(); // 释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
}
condition.signalAll(); // 唤醒所有等待的线程
}
public static void main(String[] args) {
ConditionVariableExample example = new ConditionVariableExample();
Thread thread1 = new Thread(() -> {
try {
example.criticalSection();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\nThread 1 finished execution...\n");
condition.await(); // 等待条件满足
System.out.println("Condition satisfied. All threads notified.\n");
}));
Thread thread2 = new Thread(() -> {
try {
example.criticalSection();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("\nThread 2 finished execution...\n");
condition.signalAll(); // 唤醒所有等待的线程
}));
// 启动线程
thread1.start();
thread2.start();
// 等待所有线程执行完毕
while (!thread1.isAlive() && !thread2.isAlive()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("\nProgram finished successfully!\n");
}
}
在这个例子中,我们创建了一个简单的线程同步场景。criticalSection()
方法被设计为一个需要锁定资源才能执行的代码块。
通过使用ReentrantLock和Condition接口,当多个线程同时尝试进入临界区时,可以保证只有当前持有锁的线程才能执行代码。
在条件满足时,调用condition.signalAll()来唤醒所有等待条件满足的线程。
还没有评论,来说两句吧...