问题的描述
启动3个线程打印递增的数字, 线程1先打印1,2,3,4,5, 然后是线程2打印6,7,8,9,10, 然后是线程3打印11,12,13,14,15. 接着再由线程1打印16,17,18,19,20....以此类推, 直到打印到45.
wait+notify实现:
package com.tonyluis; public class NumberPrintDemo { static int n = 1; static int state = 0; public static void main(String[] args) { new Thread(new MyThread(0)).start(); new Thread(new MyThread(1)).start(); new Thread(new MyThread(2)).start(); } } class MyThread implements Runnable{ private int state; MyThread(){ this(0); } MyThread(int state){ this.state=state; } public void run() { String threadName=Thread.currentThread().getName(); for (int i = 0; i < 3; i++) { synchronized (MyThread.class) { while (state != NumberPrintDemo.state) try { MyThread.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } for (int j = 0; j < 5; j++) System.out.println(threadName+ ": " + NumberPrintDemo.n++); System.out.println(); NumberPrintDemo.state++; NumberPrintDemo.state%=3; MyThread.class.notifyAll(); } } } }
Lock+condition实现:
package com.tonyluis; import java.util.concurrent.locks.*; public class NumberPrint { static int state = 0; static int n = 1; static Lock lock = new ReentrantLock(); static Condition condition[]=new Condition[3]; public static void main(String[] args) { for(int i=0;i<condition.length;i++) condition[i]=lock.newCondition(); new Thread(new MyThread(0)).start(); new Thread(new MyThread(1)).start(); new Thread(new MyThread(2)).start(); } } class MyThread implements Runnable{ private int state; MyThread(){ this(0); } MyThread(int state){ this.state=state; } public void run() { String threadName=Thread.currentThread().getName(); for (int i = 0; i < 5; i++) { try { NumberPrint.lock.lock(); while (state != NumberPrint.state) try { NumberPrint.condition[state].await(); } catch (InterruptedException e) { e.printStackTrace(); } for (int j = 0; j < 5; j++) System.out.println(threadName+ ": " + NumberPrint.n++); System.out.println(); NumberPrint.state++; NumberPrint.state%=NumberPrint.condition.length; NumberPrint.condition[NumberPrint.state].signal(); } finally { NumberPrint.lock.unlock(); } } } }
使用wait+notify的实现方式,在线程0进入notifyAll()方法之后,会唤醒线程1和线程2,线程1和线程2以及线程0会展开竞争,虽然最终是由线程1获得琐,过程可能比较曲折。
使用lock+condition的实现方法,线程0只会唤醒线程1,这样只有线程1和线程0展开竞争,较为精确,尤其是并发量比较大的情况下。
时间: 2024-10-27 13:52:55