日期:2014-05-16  浏览次数:20547 次

LinkedBlockingQueue 模拟抢房间座位问题

问题描述: 假设有10个房间,每个房间有5个座位。这些座位可能是空的,也可能坐着人,房间外面有大量 ? 的人等待空位,房间内的人可能随时离开,?因此要不停的扫描房间空位一旦有空的就抢座上去。

(问题是iteye的问答频道有人提出的,我做了回答)

博客原文地址 ?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