- 浏览: 1248358 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (193)
- ant/maven (6)
- algorithm (5)
- tomcat/weblogic/jboss (6)
- javascript/jquery (13)
- java (33)
- flex/flash (0)
- JPA/Hibernate/myBatis (18)
- java concurrent (7)
- test (2)
- windows/linux (6)
- java collection (7)
- design pattern (2)
- life/health (3)
- database (12)
- IDE (4)
- spring/ejb (20)
- html/css/ckeditor (7)
- jsp/servlet (3)
- java io (13)
- java security (4)
- jni (0)
- svn/git (2)
- english (2)
- java jmx (1)
- xml (1)
- struts/springmvc (9)
- middleware (2)
- cache (1)
- cglib (3)
最新评论
-
jlotusYo:
博主,真感谢。
Java 密码扩展无限制权限策略文件 -
senninha:
这个。。是api说明吧。。
ScheduledExecutorService 源码分析 -
zoutao2008:
请问大文件如何处理?按你这种方式的话,文件超过200M时就会报 ...
hessian系列之二:上传文件 -
lwj1113:
lwj1113 写道谢谢博主这么细致的demo;在系列五中通过 ...
myBatis系列之五:与Spring3集成 -
lwj1113:
谢谢博主这么细致的demo;在系列五中通过testng测试类跑 ...
myBatis系列之五:与Spring3集成
LinkedBlockingDeque是LinkedList通过ReentrantLock来实现线程安全以及阻塞,大部分方法都加了锁。
1. 构造方法
2. linkFirst和linkLast方法
3. unlink方法系列
4. BlockingDeque方法
基本流程:
a. 判断参数是否符合要求:不为null等
b. 加锁
c. 执行link或unlink操作,可能需要等待指定的时间或条件符合
d. 在finally块中释放锁
e. 返回布尔值(是否添加或删除成功)或删除的对象
比如:
5. BlockingQueue的方法
单端队列的方法大概只有双端的一半左右:
6. Stack方法
7. Collections方法
8. 迭代器
1. 构造方法
public LinkedBlockingDeque() { this(Integer.MAX_VALUE); } public LinkedBlockingDeque(int capacity) { if (capacity <= 0) throw new IllegalArgumentException(); this.capacity = capacity; } public LinkedBlockingDeque(Collection<? extends E> c) { this(Integer.MAX_VALUE); final ReentrantLock lock = this.lock; lock.lock(); // Never contended, but necessary for visibility try { for (E e : c) { if (e == null) throw new NullPointerException(); if (!linkLast(e)) // 队列已满 throw new IllegalStateException("Deque full"); } } finally { lock.unlock(); // 释放锁 } }
2. linkFirst和linkLast方法
// 将e作为首节点。如果已满,返回null private boolean linkFirst(E e) { // assert lock.isHeldByCurrentThread(); if (count >= capacity) return false; Node<E> f = first; // 当前首节点 Node<E> x = new Node<E>(e, null, f); // 新的首节点 first = x; // first指向新的首节点 if (last == null) last = x; // 只有一个节点,首尾节点相同 else f.prev = x; // 原首节点的前驱是新的首节点 ++count; notEmpty.signal(); return true; } // 将e作为尾节点。如果已满,返回null private boolean linkLast(E e) { // assert lock.isHeldByCurrentThread(); if (count >= capacity) return false; Node<E> l = last; // 当前尾节点 Node<E> x = new Node<E>(e, l, null); // 新的尾节点 last = x; // last指向新的尾节点 if (first == null) first = x; // 只有一个节点,首尾节点相同 else l.next = x; // 原尾节点的后继是新的尾节点 ++count; notEmpty.signal(); // 提醒队列非空 return true; }
3. unlink方法系列
// 删除并返回首节点。如果为空,返回null private E unlinkFirst() { // assert lock.isHeldByCurrentThread(); Node<E> f = first; // 当前首节点 if (f == null) return null; Node<E> n = f.next; // 新的首节点 E item = f.item; // 待返回的对象 f.item = null; f.next = f; // help GC first = n; // first指向新的节点 if (n == null) last = null; else n.prev = null; --count; notFull.signal(); // 提醒队列非满 return item; } // 删除并返回尾节点。如果为空,返回null private E unlinkLast() { // assert lock.isHeldByCurrentThread(); Node<E> l = last; // 当前尾节点 if (l == null) return null; Node<E> p = l.prev; // 新的尾节点 E item = l.item; // 待删除节点指向的对象 l.item = null; l.prev = l; // help GC last = p; // last指向新的尾节点 if (p == null) first = null; else p.next = null; --count; notFull.signal(); // 提醒队列非满 return item; } void unlink(Node<E> x) { // assert lock.isHeldByCurrentThread(); Node<E> p = x.prev; Node<E> n = x.next; if (p == null) { // x是首节点 unlinkFirst(); } else if (n == null) { // x是尾节点 unlinkLast(); } else { // x在中间 p.next = n; n.prev = p; x.item = null; // 节点对象被释放 // Don't mess with x's links. They may still be in use by // an iterator. --count; notFull.signal(); // 提醒队列非满 } }
4. BlockingDeque方法
基本流程:
a. 判断参数是否符合要求:不为null等
b. 加锁
c. 执行link或unlink操作,可能需要等待指定的时间或条件符合
d. 在finally块中释放锁
e. 返回布尔值(是否添加或删除成功)或删除的对象
比如:
public boolean offerFirst(E e) { if (e == null) throw new NullPointerException(); // 判断参数 final ReentrantLock lock = this.lock; lock.lock(); // 加锁 try { return linkFirst(e); // 添加操作 } finally { lock.unlock(); // 释放锁 } } public void putFirst(E e) throws InterruptedException { if (e == null) throw new NullPointerException(); final ReentrantLock lock = this.lock; lock.lock(); try { while (!linkFirst(e)) notFull.await(); // 在notFull条件上等待,直到被唤醒或中断 } finally { lock.unlock(); } } public boolean offerFirst(E e, long timeout, TimeUnit unit) throws InterruptedException { if (e == null) throw new NullPointerException(); long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); // 可以被中断 try { while (!linkFirst(e)) { if (nanos <= 0) return false; nanos = notFull.awaitNanos(nanos); // 有限时的等待 } return true; } finally { lock.unlock(); } }
5. BlockingQueue的方法
单端队列的方法大概只有双端的一半左右:
public int remainingCapacity() { final ReentrantLock lock = this.lock; lock.lock(); try { return capacity - count; } finally { lock.unlock(); } } public int drainTo(Collection<? super E> c) { return drainTo(c, Integer.MAX_VALUE); } public int drainTo(Collection<? super E> c, int maxElements) { if (c == null) throw new NullPointerException(); if (c == this) // c不可以为当前队列 throw new IllegalArgumentException(); final ReentrantLock lock = this.lock; lock.lock(); try { int n = Math.min(maxElements, count); // 参数maxElements和队列大小的较小值 for (int i = 0; i < n; i++) { c.add(first.item); // In this order, in case add() throws. unlinkFirst(); } return n; } finally { lock.unlock(); } }
6. Stack方法
public void push(E e) { addFirst(e); } public E pop() { return removeFirst(); }
7. Collections方法
public boolean remove(Object o) { return removeFirstOccurrence(o); } public Object[] toArray() { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] a = new Object[count]; int k = 0; for (Node<E> p = first; p != null; p = p.next) a[k++] = p.item; // 队列和数组指向相同的对象 return a; } finally { lock.unlock(); } } public void clear() { final ReentrantLock lock = this.lock; lock.lock(); try { for (Node<E> f = first; f != null; ) { f.item = null; Node<E> n = f.next; f.prev = null; f.next = null; f = n; } first = last = null; count = 0; notFull.signalAll(); } finally { lock.unlock(); } }
8. 迭代器
private abstract class AbstractItr implements Iterator<E> { Node<E> next; // 下个节点 E nextItem; // 下个节点指向的对象 private Node<E> lastRet; // 当前节点,由remove方法调用。 // 指向下个节点,由next()方法调用。 void advance() { final ReentrantLock lock = LinkedBlockingDeque.this.lock; lock.lock(); try { // assert next != null; Node<E> s = nextNode(next); if (s == next) { next = firstNode(); } else { while (s != null && s.item == null) // 跳过被删除的节点 s = nextNode(s); next = s; } nextItem = (next == null) ? null : next.item; } finally { lock.unlock(); } } public boolean hasNext() { return next != null; } public E next() { if (next == null) throw new NoSuchElementException(); lastRet = next; // lastRet指向下个节点,方便remove调用 E x = nextItem; // x指向下个节点的对象,nextItem在advance方法中会被修改 advance(); return x; } public void remove() { Node<E> n = lastRet; if (n == null) throw new IllegalStateException(); lastRet = null; final ReentrantLock lock = LinkedBlockingDeque.this.lock; lock.lock(); try { if (n.item != null) unlink(n); // 删除节点n } finally { lock.unlock(); } } }
发表评论
-
AtomicReferenceFieldUpdater 使用
2014-11-19 22:13 3236AtomicReferenceFieldUpdater位于ja ... -
LockSupport 分析
2014-08-03 21:26 0LockSupport 构造器是私有的,外界主要通过LockS ... -
AtomicInteger 使用
2014-08-02 22:57 3452Java中,i++和++i都不是原子操作,多线程环境下需要 ... -
死锁系列之一:模拟
2014-07-20 18:12 0死锁产生的原因是: 1. 多个线程以不同的顺序来锁共享资源 2 ... -
Java线程死锁检测
2014-07-20 12:55 0public class DeadlockDetector ... -
ExecutorService 分析
2013-03-26 18:37 2371public interface ExecutorServ ... -
Exchanger 源码分析
2013-01-29 12:35 0private Object doExchange ... -
ConcurrentHashMap 源码分析
2013-01-29 10:34 0static final int MAX_SEGM ... -
Executors 源码分析
2012-11-06 16:11 0类图: 1. 在任务的方法里面调用ExecutorServ ... -
ScheduledExecutorService 源码分析
2013-03-27 18:08 3890public interface ScheduledExe ... -
3. 共享对象
2012-05-22 11:38 0本章讲述防止多个线程同时访问某个对象。 -
LockSupport 的使用
2012-04-23 16:36 01. park方法 public static ... -
AbstractQueuedSynchronizer(3)
2012-04-20 09:28 0final boolean transferAft ... -
java concurrent (1) - 传统线程互斥和通信
2012-04-19 13:40 1919线程互斥是一次只有一个线程执行某段代码,保证数据的一致性。线程 ... -
AbstractQueuedSynchronizer(4)
2012-04-13 12:58 2483Condition是一个条件功能的class,必须放在Lock ...
相关推荐
Java concurrency之LinkedBlockingDeque详解 LinkedBlockingDeque是Java concurrency包中的一个重要类,它是双向链表实现的双向并发阻塞队列。该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时...
bitset源码Java源码分析 基础集合列表 ArrayList (done) Vector (done) LinkedList (done) Stack (done) ReferenceQueue (done) ArrayDeque (done) Set HashSet (done) TreeSet (done) LinkedHashSet (done) BitSet ...
LinkedBlockingDeque :scroll: 主要介绍LeetCode上面的算法译文,以及面试过程中遇到的实际编码问题总结。 :locked: :file_folder: :laptop: :globe_showing_Asia-Australia: :floppy_disk: :input_latin_...
6. **文档编写**:项目附带的“详细文档”可能包括需求分析、系统设计、程序流程图等,这有助于学习者学习如何撰写专业的技术文档,提高软件工程素养。 7. **版本控制**:虽然未明确提及,但一个完整的项目通常会...
高并发编程第三阶段11讲 AtomicXXXFieldUpdater源码分析及使用场景分析.mp4 高并发编程第三阶段12讲 sun.misc.Unsafe介绍以及几种Counter方案性能对比.mp4 高并发编程第三阶段13讲 一个JNI程序的编写,通过...
高并发编程第三阶段11讲 AtomicXXXFieldUpdater源码分析及使用场景分析.mp4 高并发编程第三阶段12讲 sun.misc.Unsafe介绍以及几种Counter方案性能对比.mp4 高并发编程第三阶段13讲 一个JNI程序的编写,通过...
链阻塞双端队列 LinkedBlockingDeque,并发 Map(映射) ConcurrentMap, 并发导航映射 ConcurrentNavigableMap,交换机 Exchanger, 信号量 Semaphore,执行器服务 ExecutorService, 线程池执行者 ThreadPoolExecutor,...
在Java中,可以使用`java.util.Deque`接口的实现,例如`java.util.concurrent.LinkedBlockingDeque`,它支持双端插入和删除,可以作为线程池的工作队列。 - 在创建`ThreadPoolExecutor`时,可以通过传递`...
9. 链阻塞双端队列 LinkedBlockingDeque 10. 并发 Map(映射) ConcurrentMap 11. 并发导航映射 ConcurrentNavigableMap 12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 Exchanger 15. 信号量 Semaphore ...
9. 链阻塞双端队列 LinkedBlockingDeque 10. 并发 Map(映射) ConcurrentMap 11. 并发导航映射 ConcurrentNavigableMap 12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 Exchanger 15. 信号量 Semaphore ...
链阻塞双端队列 LinkedBlockingDeque 10. 并发 Map(映射) ConcurrentMap 11. 并发导航 映射 ConcurrentNavigableMap 12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 Exchanger 15. 信号量 Semaphore ...
JAVA学习高并发的学习笔记。...BlockingQueue:ArrayBlockingQueue , DelayQueue , LinkedBlockingDeque , LinkedBlockingQueue , LinkedTransferQueue , PriorityBlockingQueue , SynchronousQueue
在给出的示例中,创建了一个`LinkedBlockingDeque`实例,并尝试向其中添加30个元素,结果同样会因栈满而阻塞。 这些同步机制对于构建高效的并发应用程序至关重要,它们可以帮助避免死锁、减少不必要的线程上下文...
9. 链阻塞双端队列 LinkedBlockingDeque 10. 并发 Map(映射) ConcurrentMap 11. 并发导航映射 ConcurrentNavigableMap 12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 Exchanger 15. 信号量 Semaphore ...
9. 链阻塞双端队列 LinkedBlockingDeque 10. 并发 Map(映射) ConcurrentMap 11. 并发导航映射 ConcurrentNavigableMap 12. 闭锁 CountDownLatch 13. 栅栏 CyclicBarrier 14. 交换机 Exchanger 15. 信号量 Semaphore ...
1. 数据结构:LRU Cache 的实现,可能使用了HashMap(用于快速查找)和Deque(如LinkedBlockingDeque或LinkedList,用于保持顺序)相结合的方式。 2. 插入操作:当有新数据插入时,首先检查LRU缓存是否已满。若已满...
### 10、阻塞队列BlockingQueue 实战及其原理分析 #### 一、阻塞队列概述 阻塞队列(BlockingQueue)是Java语言中`java.util.concurrent`包下提供的一种重要的线程安全队列。它继承自`Queue`接口,并在此基础上...
通过查看源码,我们可以深入理解如何实现生产者-消费者模型,包括线程间的同步和通信,以及如何避免常见的并发问题,如死锁、活锁和饥饿等。 总之,生产者-消费者问题是多线程编程中的经典案例,它展示了如何在多个...
例如,Java中的`java.util.concurrent.LinkedBlockingDeque`可以看作是一个环形缓冲区的实现,C++的Boost库提供了`boost::lockfree::ring_buffer`。在实际项目中,根据需求选择合适的库或自定义实现,以优化数据处理...
- **LinkedBlockingDeque**: 双端队列。 - **实现原理**: - 使用`Condition`实现通知机制,以同步队列中的生产者和消费者。 - **非阻塞队列**如`ConcurrentLinkedQueue`使用CAS算法来实现线程安全的操作。 **6. ...