Java两个线程交替打印奇偶数(两种方法对比)
简介
本文将承接文章,我们将通过“两个线程交替打印100内的奇偶数”,来展示下wait()方法和notify()方法的用法和优点,当然要体现出优点,自然要通过对比不使用这两个方法实现同一功能的代码,通过这几篇文章的讲解,帮你彻底搞懂wait()方法和notify()方法的用法。
一.仅通过synchronized关键字实现交替打印奇偶数
1.实现逻辑:
创建两个线程,一个线程负责打印奇数,另一个线程打印偶数,两个线程竞争同一个对象锁,每次打印一个数字后释放锁,然后另一个线程拿到锁打印下一个数字。
2.代码实现:
public class PrintOddEven1 { private static int count; private static final Object object = new Object(); public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { while (count < 100) { synchronized (object) { if ((count & 1) == 0) { System.out.println(Thread.currentThread().getName() + ":" + count++); } } } } }, "偶数线程").start(); new Thread(new Runnable() { @Override public void run() { while (count < 100) { synchronized (object) { if ((count & 1) == 1) { System.out.println(Thread.currentThread().getName() + ":" + count++); } } } } }, "奇数线程").start(); } }
3.结果输出:
偶数线程:0 奇数线程:1 偶数线程:2 奇数线程:3 偶数线程:4 奇数线程:5 偶数线程:6 奇数线程:7 偶数线程:8 奇数线程:9 偶数线程:10
4.结果分析:
通过创建两个线程,这两个线程共享object对象锁,当一个线程打印完一个数字后,会释放对象锁,另一个线程拿到对象锁,然后判断是否为偶数(奇数),满足条件则打印。
二.通过synchronized关键字配合wait和notify方法实现交替打印奇偶数
1.实现逻辑:
无需判断数字是否是奇偶数,两个线程通过等待唤醒机制,交替打印数字。
2.代码实现:
public class PrintOddEven2 { private static int count = 0; private static final Object object = new Object(); public static void main(String[] args) { new Thread(new printer(), "偶数线程,").start(); new Thread(new printer(), "奇数线程,").start(); } static class printer implements Runnable { @Override public void run() { while (count <= 100) { synchronized (object) { // 打印数字,并立即释放锁 System.out.println(Thread.currentThread().getName() + "打印:" + count++); object.notify(); // 此处判断,是为了打印完了100个数字后,程序能够正常结束,否则程序将一直等待下去,耗费系统资源。 if (count <= 100) { try { object.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } } }
3.结果输出:
偶数线程,打印:0 奇数线程,打印:1 偶数线程,打印:2 奇数线程,打印:3 偶数线程,打印:4 奇数线程,打印:5 偶数线程,打印:6 奇数线程,打印:7 偶数线程,打印:8 奇数线程,打印:9 偶数线程,打印:10 ……省略
4.结果分析:
此种方式,写法简洁,让线程拿到对象锁后,立即打印数字,然后通过notify()释放锁,然后调用wait()方法使线程进入等待状态。另一个线程拿到锁以后,也立即打印数字,然后通过notify()释放锁,然后进入等待状态。知道打印完100以内的所有数字,两个线程都能正常停止运行。
总结
关于synchronized关键字、wait()、notify()方法的系列教程,请参考以下文章: