`

自定义阻塞队列

 
阅读更多

阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来,如从队列中移除一个或者多个元素,或者完全清空队列,下图展示了如何通过阻塞队列来合作:

线程1往阻塞队列中添加元素,而线程2从阻塞队列中移除元素

从5.0开始,JDK在java.util.concurrent包里提供了阻塞队列的官方实现。尽管JDK中已经包含了阻塞队列的官方实现,但是熟悉其背后的原理还是很有帮助的。

1.利用wait,notify();

 

package com.thread.ticket;

import java.util.LinkedList;
import java.util.List;

public class MyBlockingQueue {
	private List queue = new LinkedList();
	private int limit;
	public MyBlockingQueue( int limit) {
		this.limit = limit;
	}
	
	public synchronized void put(Object o) throws InterruptedException {
		if(queue.size()==limit){
			wait();
		}
		if(this.queue.size()==0){
			notifyAll();
		}
		this.queue.add(o);
	}
	
    public synchronized Object get() throws InterruptedException {
    	if(this.queue.size() == 0){
    		wait();
    	}
    	if(this.queue.size() == this.limit){
    		notifyAll();
    	}
    	return queue.remove(0);
	}
	
	
	

}

 必须注意到,在enqueue和dequeue方法内部,只有队列的大小等于上限(limit)或者下限(0)时,才调用notifyAll方法。如果队列的大小既不等于上限,也不等于下限,任何线程调用enqueue或者dequeue方法时,都不会阻塞,都能够正常的往队列中添加或者移除元素。

 http://tutorials.jenkov.com/java-concurrency/blocking-queues.html

2.利用lock,Condition,await,signal

package com.thread.ticket;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BoundedBuffer {
	Lock lock = new ReentrantLock();
	final Condition notFull  = lock.newCondition(); 
	final Condition notEmpty = lock.newCondition(); 


	final Object items[] = new Object[100];
	int puter,outer,count;
	
	public void put(Object o) throws InterruptedException{
		try{
			lock.lock();
			if(items.length == count){
				notFull.await();
			}
			items[puter] = o;
			if(++puter == items.length) puter = 0;
			++count;
			notEmpty.signal();
		}finally{
			lock.unlock();
		}
	}
	
	public void take() throws InterruptedException{
		try{
			lock.lock();
			if(items.length == 0){
				notEmpty.await();
			}
			Object x= items[outer];
			if(++outer == items.length) outer = 0;
			--count;
			notFull.signal();
		}finally{
			lock.unlock();
		}
	}

}

 

分享到:
评论

相关推荐

    android自定义消息队列

    标题“android自定义消息队列”指的是开发者为Android应用创建一个自定义的消息传递机制,这通常涉及到线程间通信和任务调度。描述中的“实现的简单的开始,暂停功能”意味着这个自定义消息队列能够控制任务的执行...

    C# winform可忽略消息的自定义消息队列

    为了解决这个问题,我们可以采用自定义消息队列来优化处理流程,从而实现异步处理,避免UI线程被长时间占用。 标题中的“C# Winform可忽略消息的自定义消息队列”指的是创建一个特定的机制,允许在WinForm应用中,...

    支持多线程和泛型的阻塞队列

    C++中,虽然标准库没有内置阻塞队列,但可以利用互斥锁(mutex)、条件变量(condition variable)等同步原语自定义实现。 ### 泛型 泛型是现代编程语言中的一个重要特性,允许在不指定具体类型的情况下编写代码,...

    Android图片上传队列Service

    6. **异步处理**:为了不阻塞主线程,图片上传应该在子线程中进行。可以使用`AsyncTask`,`IntentService`,或者配合`Handler`和`Looper`来实现。这样可以保证用户界面的流畅性。 7. **通知与进度更新**:在上传...

    java线程聊天室(阻塞队列实现)

    【Java线程聊天室(阻塞队列实现)】 在Java编程中,多线程是构建并发应用程序的关键技术。在创建一个线程聊天室时,我们通常会涉及到多个线程之间的交互,例如用户发送消息、接收消息以及处理网络通信等。而阻塞...

    元素唯一的LinkedBlockingQueue阻塞队列

    通过自定义的阻塞队列,开发者可以更精确地控制并发行为,提高系统的稳定性和性能。对于想要深入理解Java并发编程和数据结构的人来说,分析和实现`UniqueLinkedBlockingQueue`是一个很好的学习机会。

    剖析Java中阻塞队列的实现原理及应用场景

    3. **PriorityBlockingQueue**:优先级队列,根据元素的自然顺序或自定义比较器进行排序。这是一个无界的阻塞队列,元素按优先级出队。 4. **DelayQueue**:基于PriorityQueue,元素需要在指定的延迟时间后才能被...

    BlockingQueue队列自定义超时时间取消线程池任务

    现在我们来详细讨论如何利用这些技术实现“BlockingQueue队列自定义超时时间取消线程池任务”。 首先,`BlockingQueue`是一个并发容器,它遵循先进先出(FIFO)原则,具有阻塞性质,当队列满时,生产者线程会被阻塞...

    Java中的阻塞队列详细介绍

    Java中的阻塞队列是一种特殊的队列数据结构,它在多线程环境下广泛应用于生产者-消费者模式。阻塞队列的主要特点在于当队列为空时,试图从中取出元素的消费者线程会被阻塞,直到有其他生产者线程添加元素;同样,当...

    FreeRTOS+STM32F103通过队列传输串口数据

    队列的创建通常在FreeRTOS任务中完成,我们需要指定队列的容量(最大可存储的数据数量)和数据类型(通常是字节、整数或自定义结构体)。创建队列后,我们就可以使用`xQueueReceive`和`xQueueSend`函数来从队列中...

    java 中 阻塞队列BlockingQueue详解及实例

    Java中的阻塞队列BlockingQueue是一种并发编程中常用的工具,它实现了线程间的同步和通信。阻塞队列的核心特性在于当队列为空时,尝试获取元素的线程会被阻塞,直到其他线程添加元素;当队列满时,尝试添加元素的...

    GCD 总结-队列和任务的理解

    主队列是同步执行的队列,所有在主队列上的任务都会在主线程上执行,确保UI更新和用户交互不会被阻塞。因此,对于修改界面的操作,应该放在主队列中。 #### 2.2 并发队列(Concurrent Queue) 并发队列可以异步执行多...

    Fastadmin消息队列插件.zip

    在实际应用中,开发者还可以根据需求自定义消息队列的任务类型,比如添加新的任务处理逻辑,比如数据分析、日志记录或者其他后台处理任务。`think-queue`提供了一套完整的API,方便开发者创建、监听和管理队列任务。...

    一个node实现队列执行的自定义处理项目发布部署命令式cli脚本工具

    标题提到的是一个使用Node.js开发的队列执行系统,它是一个命令行接口(CLI)工具,专为项目发布和部署提供自定义处理。这个工具旨在简化和优化项目的部署流程,通过队列机制确保命令按照特定顺序依次执行,避免因...

    数据结构 队列算法

    而在Python中,可以使用内置的`collections.deque`,或者自定义列表来模拟队列。此外,还可以通过链表实现队列,以减少在队列两端操作的时间复杂度。 在实验和作业中,可能会遇到的问题和练习可能包括: 1. 广义...

    Yii2队列扩展支持DBRedisRabbitMQBeanstalk和Gearman

    使用这个扩展,开发者可以轻松创建、管理和监控任务,确保复杂任务的正确执行,同时避免阻塞主线程,提升Web应用的响应速度。 在"yiisoft-yii2-queue-58b92a0"这个压缩包中,包含了Yii2队列扩展的具体实现和相关...

    基于stm32串口的环形队列应用

    通过阅读和理解这些代码,开发者可以了解到如何在实际项目中应用和自定义环形队列,以便满足不同场景的需求。 总的来说,基于STM32的串口环形队列应用是嵌入式开发中的重要一环,它提高了串口通信的效率和可靠性,...

    custom_queue:通用对象的自定义队列实现

    `custom_queue`项目旨在提供一个通用的对象自定义队列实现,它允许开发者根据具体需求定制队列的行为,例如添加特殊操作、同步机制或优化性能。该项目依赖于GSON、Google的异步库以及Jackson Core,这些库分别用于...

    workquere工作队列 多线程

    5. **工作队列实现**:`workquere`可能是自定义实现的一个工作队列类,它可能包含添加任务、启动线程、监控队列状态等功能。队列内部可能采用了`Queue`或`ConcurrentQueue`来存储待处理的任务。 6. **MSMQSample**...

Global site tag (gtag.js) - Google Analytics