题目:
审核系统有一批工单需要处理,现在启动三个线程进行处理,要求线程1处理工单id mod 3 = 1 的工单, 线程2处理工单id mod 3 = 2的工单 , 线程3处理工单id mod 3 = 0的工单,直到工单全部处理完毕,假设工单有1000个,工单编号从1-1000,工单处理过程简化为打印工单id即可,要求工单必须按顺序处理,即打印结果必须保证从1-1000从小到大递增。
方法一:
使用Synchronized+Object提供的wait()、notify()、notifyAll()方法
public class 三个线程处理1000个工单号 implements Runnable {
static int num = 1;// 开始的工单号,可以改变
static final int END = 1000;// 结束工单号
int id;// 表示线程号
Object o;// 三个线程的监视器
public 三个线程处理1000个工单号(int id, Object o) {
this.id = id;
this.o = o;
}
@Override
public void run() {
synchronized (o) {
while (num <= END) {
if (num % 3 == id) {// 如果是属于自己的数,依次打印出来
System.out.println(Thread.currentThread().getName() + "正在处理工单号: " + num);
++num;
o.notifyAll();
} else {
try {
o.wait();
} catch (InterruptedException e) {
System.out.println("线程" + id + "被打断了");
}
}
}
}
}
public static void main(String[] args) {
Object o = new Object();
new Thread(new 三个线程处理1000个工单号(1, o), "线程1").start();
new Thread(new 三个线程处理1000个工单号(2, o), "线程2").start();
new Thread(new 三个线程处理1000个工单号(0, o), "线程3").start();
}
}
方法二:使用Lock+Condition提供的await()、signal()、signalAll()
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class 三个线程处理1000个工单号 implements Runnable {
static int num = 1;// 开始的工单号,可以改变
static final int END = 1000;// 结束工单号
int id;// 表示线程号
Lock lock;
Condition condition;
public 三个线程处理1000个工单号(int id, Lock lock, Condition condition) {
this.id = id;
this.lock = lock;
this.condition = condition;
}
@Override
public void run() {
lock.lock();
try {
while (num <= END) {
if (num % 3 == id) {// 如果是属于自己的数,依次打印出来
System.out.println(Thread.currentThread().getName() + "正在处理工单号: " + num);
++num;
condition.signalAll();
} else {
try {
condition.await();
} catch (InterruptedException e) {
System.out.println("线程" + id + "被打断了");
}
}
}
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
new Thread(new 三个线程处理1000个工单号(1, lock, condition), "线程1").start();
new Thread(new 三个线程处理1000个工单号(2, lock, condition), "线程2").start();
new Thread(new 三个线程处理1000个工单号(0, lock, condition), "线程3").start();
}
}
运行结果:
线程1正在处理工单号: 1
线程2正在处理工单号: 2
线程3正在处理工单号: 3
线程1正在处理工单号: 4
线程2正在处理工单号: 5
线程3正在处理工单号: 6
线程1正在处理工单号: 7
线程2正在处理工单号: 8
线程3正在处理工单号: 9
线程1正在处理工单号: 10
线程2正在处理工单号: 11
线程3正在处理工单号: 12
线程1正在处理工单号: 13
线程2正在处理工单号: 14
线程3正在处理工单号: 15
线程1正在处理工单号: 16
线程2正在处理工单号: 17
线程3正在处理工单号: 18
线程1正在处理工单号: 19
线程2正在处理工单号: 20
.........
.........