1. 问题描述:
Robert博士要进行一场实验,她需要两个助手Alice和Bob,Alice负责从一箱试管剂中取出优先级最高的试管剂(每个试管剂
都有编号ID,规定ID最小的优先级最高)放到试管剂台容器里,该容器里只能放入一个试管剂;当Alice把试管剂放到容器里后,
就会通知Bob,然后Bob把试管剂送到Rober博士的实验室,然后Robert又会通知Alice, Alice看到容器里空了,就会放入下一个
优先级最高的试管剂并通知Bob...如此循环。
请用计算机模拟仿真该场景过程。
2. 问题分析:
这是典型的对象通信问题。即线程间的协作问题。
3. 实现方法
(1) 一箱试管剂中取出优先级最高的试管剂(每个试管剂都有编号ID,规定ID最小的优先级最高)
用优先级队列来模拟试管剂箱。
(3) Alice
(4) Bob
4. 输出结果:
Alice 把试管剂:19 放入到容器里
Bob 从容器里取走试管剂:19
Alice 把试管剂:20 放入到容器里
Bob 从容器里取走试管剂:20
Alice 把试管剂:21 放入到容器里
Bob 从容器里取走试管剂:21
Alice 把试管剂:22 放入到容器里
Bob 从容器里取走试管剂:22
Alice 把试管剂:23 放入到容器里
Bob 从容器里取走试管剂:23
Alice 把试管剂:24 放入到容器里
Bob 从容器里取走试管剂:24
Alice 把试管剂:25 放入到容器里
Bob 从容器里取走试管剂:25
Alice 把试管剂:26 放入到容器里
Bob 从容器里取走试管剂:26
Alice 把试管剂:27 放入到容器里
Bob 从容器里取走试管剂:27
Alice 把试管剂:28 放入到容器里
Bob 从容器里取走试管剂:28
Alice 把试管剂:29 放入到容器里
Bob 从容器里取走试管剂:29
Alice 把试管剂:30 放入到容器里
Bob 从容器里取走试管剂:30
Alice 把试管剂:31 放入到容器里
Bob 从容器里取走试管剂:31
Alice 把试管剂:32 放入到容器里
Bob 从容器里取走试管剂:32
Alice 把试管剂:33 放入到容器里
Bob 从容器里取走试管剂:33
Alice 把试管剂:34 放入到容器里
Bob 从容器里取走试管剂:34
Alice 把试管剂:35 放入到容器里
Bob 从容器里取走试管剂:35
Alice 把试管剂:36 放入到容器里
Bob 从容器里取走试管剂:36
Alice 把试管剂:37 放入到容器里
Bob 从容器里取走试管剂:37
Alice 把试管剂:38 放入到容器里
Bob 从容器里取走试管剂:38
Alice 把试管剂:39 放入到容器里
Bob 从容器里取走试管剂:39
Alice 把试管剂:40 放入到容器里
Bob 从容器里取走试管剂:40
Alice 把试管剂:41 放入到容器里
Bob 从容器里取走试管剂:41
Alice 把试管剂:42 放入到容器里
Bob 从容器里取走试管剂:42
Alice 把试管剂:43 放入到容器里
Bob 从容器里取走试管剂:43
Alice 把试管剂:44 放入到容器里
Bob 从容器里取走试管剂:44
Alice 把试管剂:45 放入到容器里
Bob 从容器里取走试管剂:45
Alice 把试管剂:46 放入到容器里
Bob 从容器里取走试管剂:46
Alice 把试管剂:47 放入到容器里
Bob 从容器里取走试管剂:47
Alice 把试管剂:48 放入到容器里
Bob 从容器里取走试管剂:48
Alice 把试管剂:49 放入到容器里
Bob 从容器里取走试管剂:49
Alice 把试管剂:50 放入到容器里
Bob 从容器里取走试管剂:50
Alice 把试管剂:51 放入到容器里
Bob 从容器里取走试管剂:51
Alice 把试管剂:52 放入到容器里
Bob 从容器里取走试管剂:52
Alice 把试管剂:53 放入到容器里
Bob 从容器里取走试管剂:53
Alice 把试管剂:54 放入到容器里
Bob 从容器里取走试管剂:54
Alice 把试管剂:55 放入到容器里
Bob 从容器里取走试管剂:55
Alice 把试管剂:56 放入到容器里
Bob 从容器里取走试管剂:56
Alice 把试管剂:57 放入到容器里
Bob 从容器里取走试管剂:57
Alice 把试管剂:58 放入到容器里
Bob 从容器里取走试管剂:58
Alice 把试管剂:59 放入到容器里
Bob 从容器里取走试管剂:59
Alice 把试管剂:60 放入到容器里
Bob 从容器里取走试管剂:60
Alice 把试管剂:61 放入到容器里
Bob 从容器里取走试管剂:61
Alice 把试管剂:62 放入到容器里
Bob 从容器里取走试管剂:62
Alice 把试管剂:63 放入到容器里
Bob 从容器里取走试管剂:63
Alice 把试管剂:64 放入到容器里
Bob 从容器里取走试管剂:64
Alice 把试管剂:65 放入到容器里
Bob 从容器里取走试管剂:65
Alice 把试管剂:66 放入到容器里
Bob 从容器里取走试管剂:66
Alice 把试管剂:67 放入到容器里
Bob 从容器里取走试管剂:67
Alice 把试管剂:68 放入到容器里
Bob 从容器里取走试管剂:68
Alice 把试管剂:69 放入到容器里
Bob 从容器里取走试管剂:69
Alice 把试管剂:70 放入到容器里
Bob 从容器里取走试管剂:70
Alice 把试管剂:71 放入到容器里
Bob 从容器里取走试管剂:71
Alice 把试管剂:72 放入到容器里
Bob 从容器里取走试管剂:72
Alice 把试管剂:73 放入到容器里
Bob 从容器里取走试管剂:73
Alice 把试管剂:74 放入到容器里
Bob 从容器里取走试管剂:74
Alice 把试管剂:75 放入到容器里
Bob 从容器里取走试管剂:75
Alice 把试管剂:76 放入到容器里
Bob 从容器里取走试管剂:76
Alice 把试管剂:77 放入到容器里
Bob 从容器里取走试管剂:77
Alice 把试管剂:78 放入到容器里
Bob 从容器里取走试管剂:78
Alice 把试管剂:79 放入到容器里
Bob 从容器里取走试管剂:79
Alice 把试管剂:80 放入到容器里
Bob 从容器里取走试管剂:80
Alice 把试管剂:81 放入到容器里
Bob 从容器里取走试管剂:81
Alice 把试管剂:82 放入到容器里
Bob 从容器里取走试管剂:82
Alice 把试管剂:83 放入到容器里
Bob 从容器里取走试管剂:83
Alice 把试管剂:84 放入到容器里
Bob 从容器里取走试管剂:84
Alice 把试管剂:85 放入到容器里
Bob 从容器里取走试管剂:85
Alice 把试管剂:86 放入到容器里
Bob 从容器里取走试管剂:86
Alice 把试管剂:87 放入到容器里
Bob 从容器里取走试管剂:87
Alice 把试管剂:88 放入到容器里
Bob 从容器里取走试管剂:88
Alice 把试管剂:89 放入到容器里
Bob 从容器里取走试管剂:89
Alice 把试管剂:90 放入到容器里
Bob 从容器里取走试管剂:90
Alice 把试管剂:91 放入到容器里
Bob 从容器里取走试管剂:91
Alice 把试管剂:92 放入到容器里
Bob 从容器里取走试管剂:92
Alice 把试管剂:93 放入到容器里
Bob 从容器里取走试管剂:93
Alice 把试管剂:94 放入到容器里
Bob 从容器里取走试管剂:94
Alice 把试管剂:95 放入到容器里
Bob 从容器里取走试管剂:95
Alice 把试管剂:96 放入到容器里
Bob 从容器里取走试管剂:96
Alice 把试管剂:97 放入到容器里
Bob 从容器里取走试管剂:97
Alice 把试管剂:98 放入到容器里
Bob 从容器里取走试管剂:98
Alice 把试管剂:99 放入到容器里
Bob 从容器里取走试管剂:99
Robert博士要进行一场实验,她需要两个助手Alice和Bob,Alice负责从一箱试管剂中取出优先级最高的试管剂(每个试管剂
都有编号ID,规定ID最小的优先级最高)放到试管剂台容器里,该容器里只能放入一个试管剂;当Alice把试管剂放到容器里后,
就会通知Bob,然后Bob把试管剂送到Rober博士的实验室,然后Robert又会通知Alice, Alice看到容器里空了,就会放入下一个
优先级最高的试管剂并通知Bob...如此循环。
请用计算机模拟仿真该场景过程。
2. 问题分析:
这是典型的对象通信问题。即线程间的协作问题。
3. 实现方法
(1) 一箱试管剂中取出优先级最高的试管剂(每个试管剂都有编号ID,规定ID最小的优先级最高)
用优先级队列来模拟试管剂箱。
package boke.thread4;
/**
* 基于数组的优先级队列【最小的元素具有最大优先权】
*
* @since jdk1.6
* @author 毛正吉
* @version 1.0
* @date 2010.05.25
*
*/
public class PriorityQueue {
public static void main(String[] args) throws PriorityQueueException {
PriorityQueue pq = new PriorityQueue();
pq.enQueue(10);
pq.enQueue(40);
pq.enQueue(43);
pq.enQueue(20);
pq.enQueue(50);
pq.enQueue(30);
pq.enQueue(99);
while (!pq.isEmpty()) {
int element = pq.delQueue();
System.out.print(element + " ");
}
System.out.println("");
}
private int[] pqElements;
private int count;
private static final int MAX_PQ_SIZE = 1000;
public PriorityQueue() {
pqElements = new int[MAX_PQ_SIZE];
}
public void enQueue(int item) throws PriorityQueueException {
if (!isFull()) {
pqElements[count] = item;
count++;
} else {
throw new PriorityQueueException("PriorityQueue is full!");
}
}
public int delQueue() throws PriorityQueueException {
if (!isEmpty()) {
int min = pqElements[0];
int minIndex = 0;
for (int i = 1; i < count; i++) {
if (pqElements[i] < min) {
min = pqElements[i];
minIndex = i;
}
}
pqElements[minIndex] = pqElements[count - 1];
count--;
return min;
} else {
throw new PriorityQueueException("PriorityQueue is empty!");
}
}
public void makeEmpty() {
count = 0;
}
public boolean isEmpty() {
return count == 0;
}
public boolean isFull() {
return count == MAX_PQ_SIZE;
}
public int length() {
return count;
}
}
---------------------------------------
package boke.thread4;
/**
* TODO 队列异常
*
* @since jdk1.6
* @author 毛正吉
* @version 1.0
* @date 2010.05.25
*
*/
public class PriorityQueueException extends Exception {
public PriorityQueueException() {
super("Queue Exception");
}
public PriorityQueueException(String msg) {
super(msg);
}
}
(2) 试管剂台容器,该容器里只能放入一个试管剂。
package boke.thread4;
/**
* 试管剂容器
*
* @since jdk1.6
* @author 毛正吉
* @version 1.0
* @date 2010.05.25
*
*/
public class Container {
int tubeID; // 试管剂ID
boolean isFull = false; // 容器里是否有试管剂
/**
* 容器里放入试管剂
*
* @param ID
*/
public synchronized void put(int ID) {
if (!isFull) { // 容器里没有试管剂
tubeID = ID; // 放入试管剂
System.out.println("Alice 把试管剂:" + tubeID + " 放入到容器里");
isFull = true; // 则容器里有试管剂
notify(); // 通知
}
try {
wait(); // 自己等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 从容器里取走试管剂
*
* @return
*/
public synchronized int get() {
if (!isFull) { // 容器里没有试管剂
try {
wait(); // 等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
isFull = false; // 容器里有试管剂
executeLogic(tubeID); // 执行业务逻辑
notify();// 通知
return tubeID; // 返回值
}
private void executeLogic(int value) {
System.out.println("Bob 从容器里取走试管剂:" + value);
}
}
(3) Alice
package boke.thread4;
/**
* 模拟Alice
*
* @since jdk1.6
* @author 毛正吉
* @version 1.0
* @date 2010.05.25
*
*/
class Alice extends Thread {
Container c; // 容器
PriorityQueue pq; // 优先级队列
/**
* 构造方法
*
* @param c
* @param pq
*/
Alice(Container c, PriorityQueue pq) {
this.c = c;
this.pq = pq;
}
/**
* 运行任务
*/
public void run() {
try {
while (!pq.isEmpty()) {
int ID = pq.delQueue(); // 拿出优先级最高的试管剂
c.put(ID); // 放置到容器里
}
} catch (PriorityQueueException e) {
e.printStackTrace();
}
}
}
(4) Bob
package boke.thread4;
/**
* 模拟Bob
*
* @since jdk1.6
* @author 毛正吉
* @version 1.0
* @date 2010.05.25
*
*/
class Bob extends Thread {
Container c; // 容器
PriorityQueue pq; // 优先级队列
/**
* 构造方法
*
* @param c
* @param pq
*/
Bob(Container c, PriorityQueue pq) {
this.c = c;
this.pq = pq;
}
/**
* 运行任务
*/
public void run() {
while (true) {
c.get(); // Bob从容器里取出试管剂
}
}
}
(5) 场景类Client
package boke.thread4;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 场景类
*
* @since jdk1.6
* @author 毛正吉
* @version 1.0
* @date 2010.05.25
*
*/
public class Client {
/**
*
* @param args
* @throws PriorityQueueException
*/
public static void main(String[] args) throws PriorityQueueException {
Container c = new Container(); // 容器
PriorityQueue pq = new PriorityQueue(); // 优先级队列
for (int i = 19; i < 100; i++) { // 试管剂
pq.enQueue(i);
}
Alice alice = new Alice(c, pq); // Alice
Bob bob = new Bob(c, pq); // Bob
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(alice);
exec.execute(bob);
exec.shutdown();
}
}
4. 输出结果:
Alice 把试管剂:19 放入到容器里
Bob 从容器里取走试管剂:19
Alice 把试管剂:20 放入到容器里
Bob 从容器里取走试管剂:20
Alice 把试管剂:21 放入到容器里
Bob 从容器里取走试管剂:21
Alice 把试管剂:22 放入到容器里
Bob 从容器里取走试管剂:22
Alice 把试管剂:23 放入到容器里
Bob 从容器里取走试管剂:23
Alice 把试管剂:24 放入到容器里
Bob 从容器里取走试管剂:24
Alice 把试管剂:25 放入到容器里
Bob 从容器里取走试管剂:25
Alice 把试管剂:26 放入到容器里
Bob 从容器里取走试管剂:26
Alice 把试管剂:27 放入到容器里
Bob 从容器里取走试管剂:27
Alice 把试管剂:28 放入到容器里
Bob 从容器里取走试管剂:28
Alice 把试管剂:29 放入到容器里
Bob 从容器里取走试管剂:29
Alice 把试管剂:30 放入到容器里
Bob 从容器里取走试管剂:30
Alice 把试管剂:31 放入到容器里
Bob 从容器里取走试管剂:31
Alice 把试管剂:32 放入到容器里
Bob 从容器里取走试管剂:32
Alice 把试管剂:33 放入到容器里
Bob 从容器里取走试管剂:33
Alice 把试管剂:34 放入到容器里
Bob 从容器里取走试管剂:34
Alice 把试管剂:35 放入到容器里
Bob 从容器里取走试管剂:35
Alice 把试管剂:36 放入到容器里
Bob 从容器里取走试管剂:36
Alice 把试管剂:37 放入到容器里
Bob 从容器里取走试管剂:37
Alice 把试管剂:38 放入到容器里
Bob 从容器里取走试管剂:38
Alice 把试管剂:39 放入到容器里
Bob 从容器里取走试管剂:39
Alice 把试管剂:40 放入到容器里
Bob 从容器里取走试管剂:40
Alice 把试管剂:41 放入到容器里
Bob 从容器里取走试管剂:41
Alice 把试管剂:42 放入到容器里
Bob 从容器里取走试管剂:42
Alice 把试管剂:43 放入到容器里
Bob 从容器里取走试管剂:43
Alice 把试管剂:44 放入到容器里
Bob 从容器里取走试管剂:44
Alice 把试管剂:45 放入到容器里
Bob 从容器里取走试管剂:45
Alice 把试管剂:46 放入到容器里
Bob 从容器里取走试管剂:46
Alice 把试管剂:47 放入到容器里
Bob 从容器里取走试管剂:47
Alice 把试管剂:48 放入到容器里
Bob 从容器里取走试管剂:48
Alice 把试管剂:49 放入到容器里
Bob 从容器里取走试管剂:49
Alice 把试管剂:50 放入到容器里
Bob 从容器里取走试管剂:50
Alice 把试管剂:51 放入到容器里
Bob 从容器里取走试管剂:51
Alice 把试管剂:52 放入到容器里
Bob 从容器里取走试管剂:52
Alice 把试管剂:53 放入到容器里
Bob 从容器里取走试管剂:53
Alice 把试管剂:54 放入到容器里
Bob 从容器里取走试管剂:54
Alice 把试管剂:55 放入到容器里
Bob 从容器里取走试管剂:55
Alice 把试管剂:56 放入到容器里
Bob 从容器里取走试管剂:56
Alice 把试管剂:57 放入到容器里
Bob 从容器里取走试管剂:57
Alice 把试管剂:58 放入到容器里
Bob 从容器里取走试管剂:58
Alice 把试管剂:59 放入到容器里
Bob 从容器里取走试管剂:59
Alice 把试管剂:60 放入到容器里
Bob 从容器里取走试管剂:60
Alice 把试管剂:61 放入到容器里
Bob 从容器里取走试管剂:61
Alice 把试管剂:62 放入到容器里
Bob 从容器里取走试管剂:62
Alice 把试管剂:63 放入到容器里
Bob 从容器里取走试管剂:63
Alice 把试管剂:64 放入到容器里
Bob 从容器里取走试管剂:64
Alice 把试管剂:65 放入到容器里
Bob 从容器里取走试管剂:65
Alice 把试管剂:66 放入到容器里
Bob 从容器里取走试管剂:66
Alice 把试管剂:67 放入到容器里
Bob 从容器里取走试管剂:67
Alice 把试管剂:68 放入到容器里
Bob 从容器里取走试管剂:68
Alice 把试管剂:69 放入到容器里
Bob 从容器里取走试管剂:69
Alice 把试管剂:70 放入到容器里
Bob 从容器里取走试管剂:70
Alice 把试管剂:71 放入到容器里
Bob 从容器里取走试管剂:71
Alice 把试管剂:72 放入到容器里
Bob 从容器里取走试管剂:72
Alice 把试管剂:73 放入到容器里
Bob 从容器里取走试管剂:73
Alice 把试管剂:74 放入到容器里
Bob 从容器里取走试管剂:74
Alice 把试管剂:75 放入到容器里
Bob 从容器里取走试管剂:75
Alice 把试管剂:76 放入到容器里
Bob 从容器里取走试管剂:76
Alice 把试管剂:77 放入到容器里
Bob 从容器里取走试管剂:77
Alice 把试管剂:78 放入到容器里
Bob 从容器里取走试管剂:78
Alice 把试管剂:79 放入到容器里
Bob 从容器里取走试管剂:79
Alice 把试管剂:80 放入到容器里
Bob 从容器里取走试管剂:80
Alice 把试管剂:81 放入到容器里
Bob 从容器里取走试管剂:81
Alice 把试管剂:82 放入到容器里
Bob 从容器里取走试管剂:82
Alice 把试管剂:83 放入到容器里
Bob 从容器里取走试管剂:83
Alice 把试管剂:84 放入到容器里
Bob 从容器里取走试管剂:84
Alice 把试管剂:85 放入到容器里
Bob 从容器里取走试管剂:85
Alice 把试管剂:86 放入到容器里
Bob 从容器里取走试管剂:86
Alice 把试管剂:87 放入到容器里
Bob 从容器里取走试管剂:87
Alice 把试管剂:88 放入到容器里
Bob 从容器里取走试管剂:88
Alice 把试管剂:89 放入到容器里
Bob 从容器里取走试管剂:89
Alice 把试管剂:90 放入到容器里
Bob 从容器里取走试管剂:90
Alice 把试管剂:91 放入到容器里
Bob 从容器里取走试管剂:91
Alice 把试管剂:92 放入到容器里
Bob 从容器里取走试管剂:92
Alice 把试管剂:93 放入到容器里
Bob 从容器里取走试管剂:93
Alice 把试管剂:94 放入到容器里
Bob 从容器里取走试管剂:94
Alice 把试管剂:95 放入到容器里
Bob 从容器里取走试管剂:95
Alice 把试管剂:96 放入到容器里
Bob 从容器里取走试管剂:96
Alice 把试管剂:97 放入到容器里
Bob 从容器里取走试管剂:97
Alice 把试管剂:98 放入到容器里
Bob 从容器里取走试管剂:98
Alice 把试管剂:99 放入到容器里
Bob 从容器里取走试管剂:99