如何使用Java实现多线程切换等待唤醒交替打印奇偶数
Java是一种高级的面向对象的编程语言,提供多线程的专业支持,可以在同一程序中同时执行多个线程。在多线程编程中,需要注意线程之间的同步和互斥,即一个线程在执行某些操作时,需要等待其他线程的某些操作完成后再进行下一步操作,这就需要使用到线程间的等待唤醒机制。
在本文中,我们将通过实现一个多线程切换等待唤醒的案例,来深入了解Java中的多线程和线程间的等待唤醒机制。
1. 实现思路
首先,我们需要明确本案例的需求:交替打印1~1000中的奇偶数,其中偶数由线程1打印,奇数由线程2打印。
为实现这一需求,我们需要使用到两个线程,同时需要定义一个共享变量作为打印的计数器,每次打印完成后需要把计数器加1,并在每次打印后等待对方线程的唤醒。在实现这一机制前,我们需要先了解几个重要的线程方法:wait、notify和notifyAll。
wait方法的作用是使当前线程进入等待状态,直到被唤醒或线程被中断才会退出。wait方法需要放在synchronized代码块中,表示线程在等待同步锁。当线程执行wait方法后,它会释放当前持有的同步锁,并且进入等待状态。wait方法有两种重载方法:带超时时间和不带超时时间。如果带有超时时间参数,就是在等待一定时间后自动唤醒线程。
notify方法的作用是唤醒一个在等待状态中的线程,如果有多个线程正在等待,则只唤醒其中的一个。notify方法也需要放在synchronized代码块中,表示唤醒的线程需要获取同步锁才能继续执行。
notifyAll方法的作用是唤醒所有等待状态中的线程,让它们都继续执行。notifyAll方法也需要放在synchronized代码块中,表示唤醒的线程需要获取同步锁才能继续执行。
了解了这几个线程方法后,我们就可以开始实现多线程切换等待唤醒交替打印奇偶数的案例了。
2. 实现代码
首先,我们来定义一个打印计数器count和两个线程OddThread和EvenThread。
public class WaitNotifyDemo {
private static int count = 1;
static class OddThread implements Runnable {
@Override
public void run() {
}
}
static class EvenThread implements Runnable {
@Override
public void run() {
}
}
}
在OddThread中,我们需要使用while循环不停地判断并打印奇数,同时每次打印完成后需要把count加1,并唤醒EvenThread来打印偶数。在打印完成后,需要使用wait方法进入等待状态,并释放同步锁。代码如下:
@Override
public void run() {
while(count <= 1000) {
synchronized (WaitNotifyDemo.class) {
if(count % 2 == 0) {
try {
// 继续等待偶数线程打印完毕
WaitNotifyDemo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName() + ": " + count);
count++;
// 唤醒偶数线程打印
WaitNotifyDemo.class.notify();
}
}
}
}
在EvenThread中也需要使用while循环不停地判断并打印偶数,同时每次打印完成后需要把count加1,并唤醒OddThread来打印奇数。在打印完成后,也需要使用wait方法进入等待状态,并释放同步锁。代码如下:
@Override
public void run() {
while(count <= 1000) {
synchronized (WaitNotifyDemo.class) {
if(count % 2 == 1) {
try {
// 继续等待奇数线程打印完毕
WaitNotifyDemo.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName() + ": " + count);
count++;
// 唤醒奇数线程打印
WaitNotifyDemo.class.notify();
}
}
}
}
最后,我们需要在主函数中启动两个线程并等待它们执行完毕。代码如下:
public static void main(String[] args) {
Thread thread1 = new Thread(new OddThread(), "奇数线程");
Thread thread2 = new Thread(new EvenThread(), "偶数线程");
thread1.start();
thread2.start();
try {
// 等待两个线程执行完成
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
3. 测试运行
运行以上代码,我们可以看到两个线程交替打印1~1000中的奇偶数,最终输出结果如下:
奇数线程: 1 偶数线程: 2 奇数线程: 3 偶数线程: 4 奇数线程: 5 偶数线程: 6 奇数线程: 7 偶数线程: 8 奇数线程: 9 偶数线程: 10 ... 奇数线程: 999 偶数线程: 1000
可以看到,两个线程成功地交替打印了1~1000中的奇偶数,实现了我们的需求。
4. 总结
通过本案例的实现,我们深入了解了Java中多线程切换等待唤醒的机制,学习了wait、notify和notifyAll等重要的线程方法,并成功实现了多线程交替打印奇偶数的案例。在实际开发中,多线程编程非常常见,熟练掌握多线程编程技巧是非常重要的。
