- 浏览: 979936 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
Condition条件变量很大一个程度上是为了解决Object.wait/notify/notifyAll难以使用的问题。
条件(也称为条件队列或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式释放相关的锁,并挂起当前线程,就像Object.wait 做的那样。上述API说明表明条件变量需要与锁绑定,而且多个Condition需要绑定到同一锁上。
前面的Lock中提到,获取一个条件变量的方法是Lock.newCondition()。
以上是Condition接口定义的方法,await*对应于Object.wait,signal对应于Object.notify,
signalAll对应于Object.notifyAll。特别说明的是Condition的接口改变名称就是为了避免
与Object中的wait/notify/notifyAll的语义和使用上混淆,因为Condition同样有wait/notify/notifyAll方法。每一个Lock可以有任意数据的Condition对象,Condition是与Lock绑定的,
所以就有Lock的公平性特性:如果是公平锁,线程为按照FIFO的顺序从Condition.await中释放,
如果是非公平锁,那么后续的锁竞争就不保证FIFO顺序了。一个使用Condition实现生产者消费者的模型例子如下:
在这个例子中消费take()需要队列不为空,如果为空就挂起(await()),直到收到notEmpty的信号;生产put()需要队列不满,如果满了就挂起(await()),直到收到notFull的信号。
条件(也称为条件队列或条件变量)为线程提供了一个含义,以便在某个状态条件现在可能为true 的另一个线程通知它之前,一直挂起该线程(即让其“等待”)。因为访问此共享状态信息发生在不同的线程中,所以它必须受保护,因此要将某种形式的锁与该条件相关联。等待提供一个条件的主要属性是:以原子方式释放相关的锁,并挂起当前线程,就像Object.wait 做的那样。上述API说明表明条件变量需要与锁绑定,而且多个Condition需要绑定到同一锁上。
前面的Lock中提到,获取一个条件变量的方法是Lock.newCondition()。
void await() throws InterruptedException; void awaitUninterruptibly(); long awaitNanos(long nanosTimeout) throws InterruptedException; boolean await(long time, TimeUnit unit) throws InterruptedException; boolean awaitUntil(Date deadline) throws InterruptedException; void signal(); void signalAll();
以上是Condition接口定义的方法,await*对应于Object.wait,signal对应于Object.notify,
signalAll对应于Object.notifyAll。特别说明的是Condition的接口改变名称就是为了避免
与Object中的wait/notify/notifyAll的语义和使用上混淆,因为Condition同样有wait/notify/notifyAll方法。每一个Lock可以有任意数据的Condition对象,Condition是与Lock绑定的,
所以就有Lock的公平性特性:如果是公平锁,线程为按照FIFO的顺序从Condition.await中释放,
如果是非公平锁,那么后续的锁竞争就不保证FIFO顺序了。一个使用Condition实现生产者消费者的模型例子如下:
package juc; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * Condition实现的生产者,消费者模型 * * @author donald 2017年3月2日 下午7:02:17 * @param <T> */ public class ProductQueue<T> { private final T[] items; private final Lock lock = new ReentrantLock(); private Condition notFull = lock.newCondition();// 队列非满条件 private Condition notEmpty = lock.newCondition();// 队列非空条件 //队列头,尾,当前容量 private int head, tail, count; /** * * @param maxSize */ @SuppressWarnings("unchecked") public ProductQueue(int maxSize) { items = (T[]) new Object[maxSize]; } public ProductQueue() { this(10); } /** * 生产 * @param t * @throws InterruptedException */ public void put(T t) throws InterruptedException { lock.lock(); try { while (count == getCapacity()) { // ReentrantLock is oweself, await for realse the lock and put up // the thread // when the condition is satsfy ,the get the lock and run //如果当前队列已满,则等待不满条件 notFull.await(); } //添加到队列尾部 items[tail] = t; if (++tail == getCapacity()) { //如果队列满,则将队列尾,执行队列,第一个槽 tail = 0; } //增加队列元素个数 ++count; //释放非空信号,通知所有持有当前锁lock,并等待消费的线程 notEmpty.signalAll(); } finally { lock.unlock(); } } /** * 消费 * @return * @throws InterruptedException */ public T take() throws InterruptedException { lock.lock(); try { while (count == 0) { //如果队列为空,则等待非空条件 notEmpty.await(); } T ret = items[head]; //取走队列头元素,并清空 items[head] = null;// help GC //队列元素被取万,则head指向队列头 if (++head == getCapacity()) { head = 0; } //减少队列元素数量 --count; //释放非满信号,通知所有持有当前锁lock,并等待生产的线程 notFull.signalAll(); return ret; } finally { lock.unlock(); } } /** * * @return */ public int getCapacity() { return items.length; } /** * * @return */ public int size() { lock.lock(); try { return count; } finally { lock.unlock(); } } }
在这个例子中消费take()需要队列不为空,如果为空就挂起(await()),直到收到notEmpty的信号;生产put()需要队列不满,如果满了就挂起(await()),直到收到notFull的信号。
发表评论
-
Executors解析
2017-04-07 14:38 1243ThreadPoolExecutor解析一(核心线程池数量、线 ... -
ScheduledThreadPoolExecutor解析三(关闭线程池)
2017-04-06 20:52 4450ScheduledThreadPoolExecutor解析一( ... -
ScheduledThreadPoolExecutor解析二(任务调度)
2017-04-06 12:56 2116ScheduledThreadPoolExecutor解析一( ... -
ScheduledThreadPoolExecutor解析一(调度任务,任务队列)
2017-04-04 22:59 4985Executor接口的定义:http://donald-dra ... -
ThreadPoolExecutor解析四(线程池关闭)
2017-04-03 23:02 9095Executor接口的定义:http: ... -
ThreadPoolExecutor解析三(线程池执行提交任务)
2017-04-03 12:06 6077Executor接口的定义:http://donald-dra ... -
ThreadPoolExecutor解析二(线程工厂、工作线程,拒绝策略等)
2017-04-01 17:12 3035Executor接口的定义:http://donald-dra ... -
ThreadPoolExecutor解析一(核心线程池数量、线程池状态等)
2017-03-31 22:01 20512Executor接口的定义:http://donald-dra ... -
ScheduledExecutorService接口定义
2017-03-29 12:53 1500Executor接口的定义:http://donald-dra ... -
AbstractExecutorService解析
2017-03-29 08:27 1071Executor接口的定义:http: ... -
ExecutorCompletionService解析
2017-03-28 14:27 1585Executor接口的定义:http://donald-dra ... -
CompletionService接口定义
2017-03-28 12:39 1060Executor接口的定义:http://donald-dra ... -
FutureTask解析
2017-03-27 12:59 1324package java.util.concurrent; ... -
Future接口定义
2017-03-26 09:40 1189/* * Written by Doug Lea with ... -
ExecutorService接口定义
2017-03-25 22:14 1157Executor接口的定义:http://donald-dra ... -
Executor接口的定义
2017-03-24 23:24 1671package java.util.concurrent; ... -
简单测试线程池拒绝执行任务策略
2017-03-24 22:37 2023线程池多余任务的拒绝执行策略有四中,分别是直接丢弃任务Disc ... -
JAVA集合类简单综述
2017-03-23 22:51 920Queue接口定义:http://donald-draper. ... -
DelayQueue解析
2017-03-23 11:00 1731Queue接口定义:http://donald-draper. ... -
SynchronousQueue解析下-TransferQueue
2017-03-22 22:20 2132Queue接口定义:http://donald-draper. ...
相关推荐
多线程实现生产者消费者模型:锁(Lock)、信号量(Semaphore、BoundedSemaphore)、条件(Condition)、队列(Queue)、事件(Event) 多进程程实现生产者消费者模型:信号量(Semaphore)、条件(Condition)、...
3. **生产者-消费者模型的实现** - **队列**:生产者和消费者之间通常会用到一个共享的缓冲区,也就是队列,用来存储生产者产生的数据供消费者消费。C++中可以使用`std::queue`容器来实现。 - **生产者**:生产者...
3. **生产者消费者模型的实现步骤**: - 创建一个阻塞队列作为共享数据结构。 - 生产者线程负责向队列中添加元素,当队列满时,调用`put()`方法会阻塞生产者。 - 消费者线程负责从队列中移除元素,当队列空时,...
在Java中,`java.util.concurrent`包提供了多种实现生产者消费者模型的工具,如`BlockingQueue`。 `BlockingQueue`是Java并发编程的一个核心接口,它实现了队列的数据结构,并且具备线程安全的特性。生产者可以将...
3. **条件变量**(Condition Variable):当缓冲区为空或满时,生产者和消费者可能需要等待,条件变量可以实现这种等待和唤醒机制。 4. **队列**:缓冲区通常以队列的形式实现,先进先出(FIFO)的特性保证了数据的...
通过对这些例程的分析和运行,可以深入理解生产者-消费者模型在LabVIEW中的实现方法。 8. **实际应用**:生产者-消费者模型在许多实际应用中都有所体现,如数据采集系统中,传感器作为生产者持续收集数据,而处理器...
在多线程环境中,生产者消费者模型和读者写者问题是经典的并发控制问题,它们都涉及到资源共享与同步。本主题将深入探讨如何使用编程来解决这两个问题。 首先,生产者消费者问题是多线程并发控制中的一个经典例子。...
首先,我们要理解生产者-消费者模型的基本概念。在这个模型中,生产者负责生产资源,而消费者则负责消耗这些资源。关键在于,生产者和消费者必须以一种协调的方式工作,以免出现资源过度消费或生产过剩的情况。这就...
`BlockingQueue`接口提供了线程安全的队列,自动处理了等待和唤醒操作,是实现生产者-消费者模型的一种高效方式。 4. **条件变量**:`wait()`, `notify()`和`notifyAll()`是基于条件变量的,它们可以使得线程在特定...
在计算机编程中,生产者消费者模型通常通过使用队列(Queue)数据结构来实现。队列是一种先进先出(FIFO)的数据结构,它提供了一种在生产者和消费者之间安全传递数据的方式。当生产者生成数据时,它会将数据放入...
在计算机科学中,多进程同步是一个关键的概念,用于管理和协调多个并发执行的进程,确保它们在访问共享资源时不会产生冲突。在这个场景下,我们...这个C语言实现的生产者消费者模型是学习和提升这一技能的绝佳实践。
Java实现生产者消费者模型 生产者消费者模型,是一般面试题都会考的,下面介绍使用ReetrantLock实现 生产者消费者模型。 定义一个ReentrantLock锁,同时new出两个condition,一个控制队满,一个 控制队空 //生产者 ...
在提供的压缩包文件"实验一 生产者消费者问题"中,可能包含了一个具体的C++代码实现,展示了如何运用上述概念来构建生产者消费者模型。通过分析和理解这个代码,你可以深入学习到如何在C++中使用多线程和同步机制来...
生产者消费者问题是多线程编程中的一个经典模型,用于演示如何在并发环境中通过共享资源进行协作。在这个模型中,生产者线程负责生成数据,而消费者线程则负责消费这些数据。问题的关键在于如何保证生产者不会在无处...
在《机械工业出版社 并行程序设计导论》第五章的练习题5.6中,可能要求读者设计并实现一个这样的模型,以理解和掌握OpenMP的并行化机制以及生产者消费者模式的基本概念。通常,这类练习会涉及到以下知识点: 1. **...
生产者-消费者模型涉及到两个主要角色:生产者(Producer)和消费者(Consumer)。生产者负责生成数据或产品,并将其放入一个共享的缓冲区;而消费者则从这个缓冲区中取出并消费这些数据或产品。在我们的例子中,有...
这个库提供了多种工具类,如Semaphore(信号量)、BlockingQueue(阻塞队列)和Condition(条件变量),这些都可以用来实现生产者-消费者模型。 1. **BlockingQueue**: 阻塞队列是一种特殊的队列,它具有线程安全的...
生产者消费者问题是多线程编程中的一个经典案例,它展示了如何通过共享资源在并发环境中实现线程间的协调。在这个问题中,"生产者"线程负责生成数据,而"消费者"线程则负责消费这些数据。MFC(Microsoft Foundation ...