一、引言
在多线程编程中,线程间的同步和通信是一个重要的主题。本文将探讨如何使用Java实现两个线程按照一定顺序交替打印字符A和B。
二、方法概述
- 使用
java.util.concurrent.locks.ReentrantLock与Condition - 使用
synchronized关键字 - 使用
Semaphore
三、具体实现
1. 使用ReentrantLock与Condition
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Data {
private final Lock lock = new ReentrantLock();
private final Condition conditionA = lock.newCondition();
private final Condition conditionB = lock.newCondition();
private int flag = 0;
public void printA() throws InterruptedException {
lock.lock();
try {
while (flag != 0) {
conditionA.await();
}
System.out.println("当前线程:" + Thread.currentThread().getName() + ", 打印:A, 当前flag: " + flag);
flag = 1;
conditionB.signal();
} finally {
lock.unlock();
}
}
public void printB() throws InterruptedException {
lock.lock();
try {
while (flag != 1) {
conditionB.await();
}
System.out.println("当前线程:" + Thread.currentThread().getName() + ", 打印:B, 当前flag: " + flag);
flag = 0;
conditionA.signal();
} finally {
lock.unlock();
}
}
}
2. 使用synchronized关键字
public class Data {
private int flag = 0;
public synchronized void printA() throws InterruptedException {
while (flag != 0) {
this.wait();
}
System.out.println("当前线程:" + Thread.currentThread().getName() + ", 打印:A, 当前flag: " + flag);
flag = 1;
this.notifyAll();
}
public synchronized void printB() throws InterruptedException {
while (flag != 1) {
this.wait();
}
System.out.println("当前线程:" + Thread.currentThread().getName() + ", 打印:B, 当前flag: " + flag);
flag = 0;
this.notifyAll();
}
}
3. 使用Semaphore
import java.util.concurrent.Semaphore;
public class MethodThree {
public static void main(String[] args) {
Semaphore semaphoreA = new Semaphore(0); // A开始时等待
Semaphore semaphoreB = new Semaphore(1); // B开始时允许执行
Thread threadA = new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
semaphoreA.acquire();
System.out.println("当前线程:" + Thread.currentThread().getName() + ", 打印:A");
semaphoreB.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "Thread-A");
Thread threadB = new Thread(() -> {
for (int i = 0; i < 10; i++) {
try {
semaphoreB.acquire();
System.out.println("当前线程:" + Thread.currentThread().getName() + ", 打印:B");
semaphoreA.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "Thread-B");
threadA.start();
threadB.start();
}
}
四、总结
以上三种方法都可以实现线程之间的有序交互。选择哪种方法取决于实际需求以及对性能和可读性的考虑。使用synchronized和ReentrantLock提供了一种更直接的方式去控制线程的执行顺序,而Semaphore则提供了基于许可的控制机制,适用于更复杂的场景。