问题描述: 假设有10个房间,每个房间有5个座位。这些座位可能是空的,也可能坐着人,房间外面有大量 的人等待空位,房间内的人可能随时离开, 因此要不停的扫描房间空位一旦有空的就抢座上去。
博客原文地址 http://sprite311.iteye.com/blog/2033655
解决思路:
1涉及到多线的安全问题,调查到LinkedBlockingQueue 是java.util.concurrent包下的线程安全的阻塞 队列,用之;
2房间里的座位类似生产者的产品;
3 一个队列模拟一个房间,涉及到多个房间使用队列数组来模拟;
4生产者向队列里放数据(人进入房间)使用offer()方法而不使用put()方法,因为put条件不满足时是阻塞的;
5使用Random来模拟人随机的去某个房间排队;
代码:
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
/**
*
*
* 描述: 假设有10个房间,每个房间有5个座位。这些座位可能是空的,也可能坐着人,房间外面有大量的人等待空位,房间内的人可能随时离开,
* 因此要不停的扫描房间空位一旦有空的就抢座上去。
* 创建人:田超
* 创建时间:2014-3-19 下午4:34:32
* blog:http://sprite311.iteye.com/
*
*/
public class MultiRoomSeatCompetition {
private static int roomCount = 10;
public static void main(String[] args) {
// 所有房间的数组集合
LinkedBlockingQueue<String>[] roomArray = new LinkedBlockingQueue[roomCount];
for (int i = 0; i < roomCount; i++) {
roomArray[i] = new LinkedBlockingQueue<String>(5);
}
System.out
.println("创建了" + roomArray.length + "个房间-------------------。");
// System.out.println(roomArray[0].size());
Consumer c11 = new Consumer("消费者01号", roomArray, roomCount);
Producer p11 = new Producer("生产者01号", roomArray, roomCount);
Producer p22 = new Producer("生产者02号", roomArray, roomCount);
Producer p33 = new Producer("生产者03号", roomArray, roomCount);
Producer p44 = new Producer("生产者04号", roomArray, roomCount);
Producer p55 = new Producer("生产者05号", roomArray, roomCount);
Producer p66 = new Producer("生产者06号", roomArray, roomCount);
Producer p77 = new Producer("生产者07号", roomArray, roomCount);
Producer p88 = new Producer("生产者08号", roomArray, roomCount);
Producer p99 = new Producer("生产者09号", roomArray, roomCount);
ExecutorService service = Executors.newCachedThreadPool();
service.submit(c11);
service.submit(p11);
service.submit(p22);
service.submit(p33);
service.submit(p44);
service.submit(p55);
service.submit(p66);
service.submit(p77);
service.submit(p88);
service.submit(p99);
}
}
/**
* 生产者 (排队的人 :类似生产者的产品)
*/
class Producer implements Runnable {
private String pname;
private LinkedBlockingQueue[] roomArray;
private int roomCount;
public Producer(String pname, LinkedBlockingQueue[] roomArray, int roomCount) {
this.pname = pname;
this.roomArray = roomArray;
this.roomCount = roomCount;
}
public void run() {
try {
while (true) {
UUID productID = UUID.randomUUID();
Random r = new Random();
int i = r.nextInt(roomCount);
boolean isEnter = roomArray[i].offer(String.valueOf(productID));
if (isEnter) {
System.out.println("在" + i + "号房排队的" + productID + "已经进入"
+ i + "号房,房间里现在有" + roomArray[i].size() + "个人");
}
// Thread.sleep(500);
}
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
/**
* 消费者 :将房间里的人取走的线程
*/
class Consumer implements Runnable {
private String cname;
private LinkedBlockingQueue[] roomArray;
private int roomCount;
public Consumer(String cname, LinkedBlockingQueue[] roomArray, int roomCount) {
this.cname = cname;
this.roomArray = roomArray;
this.roomCount = roomCount;
}
public void run() {
try {
while (true) {
Random r = new Random();
int i = r.nextInt(roomCount);
String product = (String) roomArray[i].take();
System.out.println(product + "已经离开了" + i + "号房,房间里现在有"
+ roomArray[i].size() + "个人");
Thread.sleep(5000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
存在的问题:假如房间满的,某个人没能进去,那他就被抛弃了--!
我觉得可以维护一个集合,存进入房间失败的人,集合为空才生产新的人