`

LinkedBlockingQueue 模拟抢房间座位问题

 
阅读更多

问题描述: 假设有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();
		}
	}
}

 

存在的问题:假如房间满的,某个人没能进去,那他就被抛弃了--!
我觉得可以维护一个集合,存进入房间失败的人,集合为空才生产新的人

                 

分享到:
评论
1 楼 huzhanchi 2014-03-19  
mark 学习下

相关推荐

    linkedblockingqueue

    《LinkedBlockingQueue深度解析与应用实践》 在Java并发编程领域,`LinkedBlockingQueue`是一个不可或缺的工具。作为`java.util.concurrent`包中的一个线程安全的队列,它基于链表结构实现,具备先进先出(FIFO)的...

    LinkedBlockingQueue 和 ConcurrentLinkedQueue的区别.docx

    《LinkedBlockingQueue与ConcurrentLinkedQueue的比较与应用》 在Java并发编程中,队列是一种重要的数据结构,尤其在多线程环境下的任务调度和数据传递中扮演着关键角色。LinkedBlockingQueue和...

    LinkedBlockingQueue + 单向链表基本结构

    《深入理解LinkedBlockingQueue与单向链表结构》 LinkedBlockingQueue是Java并发包`java.util.concurrent`中的一个先进先出(FIFO)队列,它基于链表结构实现,特别适用于高并发场景。该队列的主要特点是其内部数据...

    java多线程模拟抢红包功能

    Java 多线程模拟抢红包功能 本文主要介绍了 Java 多线程模拟抢红包功能,通过使用多线程和阻塞队列实现抢红包的功能。该功能可以模拟多个人抢红包的场景,具有很高的参考价值。 一、多线程编程 多线程编程是 Java...

    并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    ### 并发队列 ConcurrentLinkedQueue 和阻塞队列 LinkedBlockingQueue 用法详解 #### 一、并发队列 ConcurrentLinkedQueue 概述 `ConcurrentLinkedQueue` 是 Java 并发包 `java.util.concurrent` 提供的一个高性能...

    LinkedBlockingQueuejava.pdf

    LinkedBlockingQueuejava.pdf

    详细分析Java并发集合LinkedBlockingQueue的用法

    LinkedBlockingQueue使用ReentrantLock实现同步锁,用于处理插入队列操作的并发问题,例如put和offer操作。同时,LinkedBlockingQueue也使用Condition实现条件变量,用于队列为空和队列已满的情况下阻塞等待。 四、...

    并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解

    "并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解" ArrayBlockingQueue和LinkedBlockingQueue是Java并发容器中两个常用的阻塞队列实现,分别基于数组和链表存储元素。它们都继承自AbstractQueue类...

    JDK容器学习之Queue:LinkedBlockingQueue

    本篇文章将深入探讨`LinkedBlockingQueue`,这是一个基于链表结构的无界阻塞队列,常用于线程池的创建中作为任务缓冲队列。 首先,我们来看一下`LinkedBlockingQueue`的底层数据结构。与数组结构的`...

    元素唯一的LinkedBlockingQueue阻塞队列

    《元素唯一的LinkedBlockingQueue阻塞队列》 在Java并发编程中,`LinkedBlockingQueue`是一种基于链表结构的阻塞队列,它在多线程环境下的性能表现优秀,常用于实现生产者消费者模型。这个队列的一个关键特性是其...

    生产者/消费者模式 阻塞队列 LinkedBlockingQueue

    同时,作为阻塞队列,当生产者尝试向满队列添加元素时,或者消费者尝试从空队列中获取元素时,线程会被阻塞,直到队列有可用空间或数据,这大大简化了多线程同步的问题。 在生产者/消费者模式中,生产者通常通过`...

    java中LinkedBlockingQueue与ArrayBlockingQueue的异同

    Java中的`LinkedBlockingQueue`和`ArrayBlockingQueue`都是`java.util.concurrent`包下的线程安全队列,它们都实现了`BlockingQueue`接口,提供了一种高效、线程安全的数据同步方式。这两种队列在很多方面都有相似之...

    java模拟生产者和消费者问题

    标题和描述中的知识点聚焦于Java语言中通过模拟“生产者-消费者”问题来演示线程同步和阻塞机制。此问题通常用于理解并发编程中资源的共享与竞争,尤其是在多线程环境中。以下是对该主题的详细解析: ### 生产者-...

    java多线程模拟队列实现排队叫号

    在“java多线程模拟队列实现排队叫号”这一主题中,我们将深入探讨如何利用这两种技术来模拟现实生活中常见的排队叫号系统。 首先,多线程是指一个程序中可以同时执行多个独立的执行流,每个执行流被称为一个线程。...

    操作系统模拟:生产者消费者

    操作系统模拟:生产者消费者模型是计算机科学中一种经典的多线程同步问题,它模拟了现实世界中的生产者(Producer)和消费者(Consumer)之间的交互。在这个模型中,生产者负责生成数据,而消费者则负责消费这些数据...

    多线程模拟实现生产者/消费者模型

    在Java中,我们可以使用`ArrayBlockingQueue`、`LinkedBlockingQueue`等类型的`BlockingQueue`作为缓冲区。 2. **生产者线程**:负责生成商品并将其放入缓冲区。当缓冲区满时,生产者会被阻塞,直到有空间可用。 3...

    java编写的一个多线程程序,模拟银行排队.zip

    这个名为“BankDemo”的程序就是一个很好的实例,它展示了如何使用Java来模拟一个银行排队系统。在这个系统中,我们可以预想有多个客户(线程)同时等待服务,而银行只有一个服务窗口(线程)。下面我们将深入探讨这...

    java 银行业务队列简单模拟

    在Java编程领域,银行业务处理通常涉及到大量的并发操作和数据一致性问题。为了高效地处理这些事务,我们可以使用队列作为核心机制来实现一个简单的银行业务模拟。在这个项目中,我们将探讨如何利用Java语言和相关...

Global site tag (gtag.js) - Google Analytics