用Java线程协作模拟 - Alice,Bob和Robert博士的协作

1. 问题描述:

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值