摘自别人,仅供分析
/*
编写一个线程安全、大小固定的队列
提供阻塞式的方法put,若队列没有空间,则方法put会一直等待
提供阻塞式的方法take,若队列为空,则方法take会一直等待
启动30个线程操作该队列,每个线程进行一次put和一次take操作
*/
/*
已经按照顺序获得读锁和写锁了,但是如果启动30个线程的话,基本上每次都会死锁,线程都停在read_lock.wait()的位置,
如果启动20个线程就只有一半的几率会死锁(其实都在等待read_lock的锁,不能说是死锁),但每一个线程take一次必然会put一次,
或者反过来,按说是不会有都等待read_lock的情况
*/
package com.wei.test;
import java.util.*;
public class Queue1
{
final int SIZE = 10; //队列固定大小
ArrayList store = new ArrayList(SIZE);
Object write_lock = new Object();//用于对store的写操作,如get/add/set/remove
Object read_lock = new Object(); //用于对store只读操作,如取size
public Queue1(){}
public void put (Object o) //没有空间一直等待
{
while(true){
synchronized(read_lock){
try{
if(store.size() == SIZE){
read_lock.wait();//如果队列已满,就释放锁
}else{
synchronized(write_lock){
Thread.sleep(50);
store.add(o); //增加元素到队列
System.out.println(Thread.currentThread().getName() + "****PUT::Size=" + store.size());
Thread.sleep(50);
read_lock.notifyAll(); //通知其他线程
break;
}
}
}catch(Exception ex){
ex.printStackTrace(System.err);
}
}
}
}
public Object take () //没有数据一直等待
{
while(true){
synchronized(read_lock){
try{
if(store.size() == 0){
read_lock.wait();//如果队列没有数据,就释放锁
}else{
synchronized(write_lock){
Thread.sleep(50);
Object obj = store.remove(0); //从队列头移走数据
System.out.println(Thread.currentThread().getName() + "****Take::Size=" + store.size());
Thread.sleep(50);
read_lock.notifyAll();//通知其他线程
return obj;
}
}
}catch(Exception ex){
ex.printStackTrace(System.err);
}
}
}
}
public static void main(String[] args){
Queue1 queue1 = new Queue1(); //创建一个队列
for(int i = 0; i < 30; i++){ //启动30个线程访问队列
TestThread thread = new TestThread(queue1,i);
System.out.println( "--Thread:" + i + " Start!" );
thread.start();
try{
Thread.sleep(10); //没隔十毫秒启动一个线程
}catch(Exception ex){
ex.printStackTrace(System.err);
}
}
}
}
class TestThread extends Thread
{
Queue1 queue1 = null;
int sn = 0;
public TestThread(Queue1 queue1,int sn){
this.queue1 = queue1;
this.sn = sn;
setName("Thread::" + sn); //以序号作为线程名
}
public void run(){
String tmp = null;
try{
if( sn < 7){ //sn小于7的线程先put,后take
tmp = "Thread-PUT::" + sn + "---put::";
queue1.put(tmp);
Thread.sleep(10);
tmp = "Thread-Take::" + sn + "---take::";
Object obj = queue1.take();
}else{ //sn大于7的线程先take,后put
tmp = "Thread-Take::" + sn + "---take::";
Object obj = queue1.take();
Thread.sleep(10);
tmp = "Thread-PUT::" + sn + "---put::";
queue1.put(tmp);
}
System.out.println("Thread::" + sn + " task over!");
}catch(Exception ex){
ex.printStackTrace(System.err);
}
}
}
http://bbs.firnow.com/dview1t79413.html
分享到:
相关推荐
阻塞队列是一种在多线程编程中广泛使用的并发数据结构,它在计算机科学和编程领域,特别是Java和C++等面向对象语言中扮演着重要角色。标题中的“支持多线程和泛型的阻塞队列”意味着我们讨论的是一个能够同时处理多...
Java中的阻塞队列是一种基于同步原语的高级数据结构,它在多线程编程中扮演着重要角色,尤其在并发处理和优化系统资源利用率方面。阻塞队列结合了队列的数据结构与线程同步机制,使得生产者可以在队列满时被阻塞,而...
在Java编程语言中,阻塞队列是一种线程安全的数据结构,它在多线程并发控制中发挥着重要作用。阻塞队列的核心特性是当队列为空时,尝试获取元素的线程会被阻塞,直到其他线程添加元素;同样,当队列满时,试图插入...
C++11 中的阻塞队列是指在多线程环境下,实现生产者消费者模式的队列。阻塞队列的实现需要解决两个问题:线程安全和阻塞机制。在 C++11 中,我们可以使用 std::mutex、std::condition_variable 和 std::queue 等标准...
阻塞队列为线程间通信提供了便捷的机制,可以用来协调多个线程的运行,防止多线程直接访问共享资源导致的并发问题。例如,生产者-消费者问题就可以通过阻塞队列来优雅地解决。生产者在队列满时会被阻塞,直到队列有...
2. 需要更多的同步机制:阻塞队列需要更多的同步机制来避免线程之间的冲突。 阻塞队列是一种非常有用的数据结构,它可以帮助我们解决很多问题,但是也需要我们小心地使用它,以免引起更多的问题。
【Java线程聊天室(阻塞队列实现)】 在Java编程中,多线程是构建并发应用程序的关键技术。在创建一个线程聊天室时,我们通常会涉及到多个线程之间的交互,例如用户发送消息、接收消息以及处理网络通信等。而阻塞...
### BlockingQueue(阻塞队列)详解 #### 一、前言 随着现代软件系统对并发性能需求的不断提高,多线程编程技术逐渐成为开发人员不可或缺的技能之一。在Java平台中,`java.util.concurrent`包提供了丰富的工具来...
在Java编程中,"并发-线程池和阻塞队列"是两个核心概念,它们在多线程环境下处理任务调度和数据同步方面发挥着重要作用。线程池是一种管理线程资源的有效方式,而阻塞队列则常用于线程间通信和数据共享。 线程池...
2. **非阻塞操作**:为了优化性能,队列的读写操作应该尽可能地减少阻塞。例如,当队列为空时,消费者线程不应无限等待,而是应该被通知并进入休眠状态,直到有新的任务到来。 3. **公平性与效率**:在设计任务队列...
2. **阻塞队列**:一种常见的队列实现是阻塞队列,当队列为空时,尝试取元素的线程会被阻塞,直到有新的元素加入;同样,当队列满时,试图插入元素的线程也会被阻塞。这样可以防止资源浪费,线程可以根据队列的状态...
在Java编程中,阻塞队列是一种特殊类型的并发数据结构,它在多线程环境中的应用广泛,主要用于线程间的协作通信。阻塞队列在队列满时会阻止生产者线程添加元素,在队列空时会阻止消费者线程取出元素,直到条件满足...
线程消息队列是并发编程中一种常见的同步和通信机制,尤其在多线程环境和异步处理中扮演着重要角色。它通过提供一个数据结构,即消息队列,来协调多个生产者线程和一个或多个消费者线程之间的交互。这种设计模式允许...
同时,作为阻塞队列,当生产者尝试向满队列添加元素时,或者消费者尝试从空队列中获取元素时,线程会被阻塞,直到队列有可用空间或数据,这大大简化了多线程同步的问题。 在生产者/消费者模式中,生产者通常通过`...
阻塞队列(BlockingQueue)是Java语言中`java.util.concurrent`包下提供的一种重要的线程安全队列。它继承自`Queue`接口,并在此基础上增加了额外的功能:当线程尝试往一个已满的队列中添加元素时,该线程会被阻塞,...
- 慎重选择队列大小,过大可能导致内存浪费,过小可能导致频繁的线程阻塞和唤醒,影响性能。 - 考虑异常处理,避免在队列操作中抛出异常导致线程中断。 通过深入理解和熟练使用阻塞队列,可以有效提高Java并发程序...
阻塞队列是Java中并发编程的一个重要组件,它属于Java.util.concurrent包中的一部分。...使用阻塞队列能够极大地简化生产者和消费者模型的实现,并且能够在多线程环境中更加有效地管理资源和任务。
阻塞队列在多线程环境中特别有用,因为它允许线程在队列满时等待,直到有空间可用;同样,当队列为空时,取元素的线程也会被阻塞,直到有新的元素插入。 常见的`BlockingQueue`实现包括`ArrayBlockingQueue`、`...
当队列满或空时,`wait()`方法被调用,将当前线程阻塞;而当其他线程改变了队列状态(添加或移除元素),通过调用`notifyAll()`唤醒所有等待的线程。 值得注意的是,这个简单的实现没有使用Java并发库中的`Lock`和`...
Java中的阻塞队列是一种特殊的线程安全的数据结构,它在多线程环境下用于高效地处理生产者-消费者问题。阻塞队列的核心特性在于当队列为空时,尝试获取元素的线程会被阻塞,直到队列中有元素可用;同样,当队列满时...