简介
本文将承接文章《Java多线程wait()和notify()系列方法使用教程》,我们将通过“两个线程交替打印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以内的所有数字,两个线程都能正常停止运行。
总结
本文作为wait()
和notify()
方法的用法示例教程,展示wait()
和notify()
方法的用法,下一篇文章将再展示一个wait()
和notify()
方法的使用案例《设计模式之消费者生产者模式》,将带大家继续领悟下线程唤醒通知机制使用意义所在。
建议收藏:
关于synchronized关键字
、wait()
、notify()
方法的系列教程,请参考以下文章:
《Java中synchronized实现类锁的两种方式及原理解析》
《Java中synchronized实现对象锁的两种方式及原理解析》
《Java多线程wait()和notify()系列方法使用教程》
《Java中Synchronized的可重入性和不可中断性的分析和代码验证》