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()方法的系列教程,请参考以下文章:

经验分享 程序员 微信小程序 职场和发展