Java实现两个线程交替打印
在多线程编程中,我们经常需要控制线程的执行顺序,以实现特定的功能。例如,我们可能需要两个线程交替执行某些操作。在Java中,我们可以通过多种方式来实现这一需求,如使用wait()
和notify()
方法、使用ReentrantLock
和Condition
等。本文将介绍一种简单的方法,使用Object
类的wait()
和notify()
方法来实现两个线程交替打印。
线程交替打印的原理
线程交替打印的核心原理是利用wait()
和notify()
方法实现线程间的协作。当一个线程执行完自己的任务后,它会调用wait()
方法进入等待状态,同时通知另一个线程执行。当另一个线程执行完毕后,它会调用notify()
方法唤醒等待的线程。
代码实现
下面是一个简单的示例,演示如何使用wait()
和notify()
方法实现两个线程交替打印:
public class AlternatePrinting {
private boolean flag = true;
public synchronized void printA() {
while (true) {
while (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread A");
flag = false;
notifyAll();
}
}
public synchronized void printB() {
while (true) {
while (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Thread B");
flag = true;
notifyAll();
}
}
public static void main(String[] args) {
AlternatePrinting ap = new AlternatePrinting();
Thread threadA = new Thread(() -> ap.printA(), "Thread A");
Thread threadB = new Thread(() -> ap.printB(), "Thread B");
threadA.start();
threadB.start();
}
}
在这个示例中,我们定义了一个AlternatePrinting
类,其中包含两个方法printA()
和printB()
,分别用于线程A和线程B的打印操作。这两个方法都是同步的,以确保线程安全。
在printA()
方法中,我们首先检查flag
变量是否为true
。如果不是,线程A会进入等待状态,直到flag
变为true
。当线程B执行完毕后,它会将flag
设置为true
并调用notifyAll()
方法唤醒等待的线程A。
类似地,在printB()
方法中,我们首先检查flag
变量是否为false
。如果不是,线程B会进入等待状态,直到flag
变为false
。当线程A执行完毕后,它会将flag
设置为false
并调用notifyAll()
方法唤醒等待的线程B。
关系图
下面是一个使用Mermaid语法绘制的关系图,展示了线程A和线程B之间的协作关系:
erDiagram
ThreadA ||--o{ AlternatePrinting : printA
ThreadB ||--o{ AlternatePrinting : printB
AlternatePrinting {
boolean flag
void printA()
void printB()
}
流程图
下面是一个使用Mermaid语法绘制的流程图,展示了线程交替打印的执行流程:
flowchart TD
A[线程A执行] --> B{检查flag}
B -- 是 --> C[调用wait()等待]
B -- 否 --> D[打印Thread A]
D --> E[设置flag为false]
E --> F[调用notifyAll()]
F --> G[线程B执行]
G --> H{检查flag}
H -- 是 --> I[调用wait()等待]
H -- 否 --> J[打印Thread B]
J --> K[设置flag为true]
K --> L[调用notifyAll()]
L --> A
结语
通过本文的介绍,我们了解到了如何使用Java中的wait()
和notify()
方法实现两个线程的交替打印。这种方法简单易用,适用于需要控制线程执行顺序的场景。当然,还有其他更高级的方法,如使用ReentrantLock
和Condition
,可以根据具体需求选择合适的实现方式。