ArrayBlockingQueue的实现思路简单描述,ArrayBlockingQueue的底对于互斥访问使用的一个锁。细节参考源码take和put方法:

  1. import java.util.concurrent.TimeUnit;
  2. import java.util.concurrent.locks.*;
  3. import java.util.*;
  4.  
  5. public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {
  6.  
  7. /** The queued items */
  8. final Object[] items;//证明了java泛型是语法级别的泛型。
  9.  
  10. /** items index for next take, poll, peek or remove */
  11. int takeIndex;
  12.  
  13. /** items index for next put, offer, or add */
  14. int putIndex;
  15.  
  16. // 可以使用一个int变量计数原因是:ArrayBlockingQueue的实现只有一把锁,对count访问时候都是在锁的保护机制下实现互斥的。
  17. /** Number of elements in the queue */
  18. int count;
  19.  
  20. /*
  21. * Concurrency control uses the classic two-condition algorithm found in any
  22. * textbook.
  23. */
  24. // 使用一把锁
  25. /** Main lock guarding all access */
  26. final ReentrantLock lock;
  27.  
  28. // 两个Condition对象
  29. /** Condition for waiting takes */
  30. private final Condition notEmpty;
  31. /** Condition for waiting puts */
  32. private final Condition notFull;
  33.  
  34. /**
  35. * Circularly decrement i.
  36. */
  37. final int dec(int i) {
  38. return ((i == 0) ? items.length : i) - 1;
  39. }
  40.  
  41. @SuppressWarnings("unchecked")
  42. static <E> E cast(Object item) {
  43. return (E) item;
  44. }
  45.  
  46. /**
  47. * Returns item at index i.
  48. */
  49. final E itemAt(int i) {
  50. return this.<E>cast(items[i]);
  51. }
  52.  
  53. /**
  54. * Throws NullPointerException if argument is null.
  55. *
  56. * @param v
  57. * the element
  58. */
  59. private static void checkNotNull(Object v) {
  60. if (v == null)
  61. throw new NullPointerException();
  62. }
  63.  
  64. /**
  65. * Deletes item at position i. Utility for remove and iterator.remove. Call
  66. * only when holding lock.
  67. */
  68. void removeAt(int i) {
  69. final Object[] items = this.items;
  70. // if removing front item, just advance
  71. if (i == takeIndex) {
  72. items[takeIndex] = null;
  73. takeIndex = inc(takeIndex);
  74. } else {
  75. // slide over all others up through putIndex.
  76. for (;;) {
  77. int nexti = inc(i);
  78. if (nexti != putIndex) {
  79. items[i] = items[nexti];
  80. i = nexti;
  81. } else {
  82. items[i] = null;
  83. putIndex = i;
  84. break;
  85. }
  86. }
  87. }
  88. --count;
  89. notFull.signal();
  90. }
  91.  
  92. /**
  93. * Creates an {@code ArrayBlockingQueue} with the given (fixed) capacity and
  94. * default access policy.
  95. *
  96. * @param capacity
  97. * the capacity of this queue
  98. * @throws IllegalArgumentException
  99. * if {@code capacity < 1}
  100. */
  101. public ArrayBlockingQueue(int capacity) {
  102. this(capacity, false);
  103. }
  104.  
  105. /**
  106. * Creates an {@code ArrayBlockingQueue} with the given (fixed) capacity and
  107. * the specified access policy.
  108. *
  109. * @param capacity
  110. * the capacity of this queue
  111. * @param fair
  112. * if {@code true} then queue accesses for threads blocked on
  113. * insertion or removal, are processed in FIFO order; if
  114. * {@code false} the access order is unspecified.
  115. * @throws IllegalArgumentException
  116. * if {@code capacity < 1}
  117. */
  118. public ArrayBlockingQueue(int capacity, boolean fair) {
  119. if (capacity <= 0)
  120. throw new IllegalArgumentException();
  121. this.items = new Object[capacity];
  122. lock = new ReentrantLock(fair);
  123. notEmpty = lock.newCondition();
  124. notFull = lock.newCondition();
  125. }
  126.  
  127. /**
  128. * Creates an {@code ArrayBlockingQueue} with the given (fixed) capacity,
  129. * the specified access policy and initially containing the elements of the
  130. * given collection, added in traversal order of the collection's iterator.
  131. *
  132. * @param capacity
  133. * the capacity of this queue
  134. * @param fair
  135. * if {@code true} then queue accesses for threads blocked on
  136. * insertion or removal, are processed in FIFO order; if
  137. * {@code false} the access order is unspecified.
  138. * @param c
  139. * the collection of elements to initially contain
  140. * @throws IllegalArgumentException
  141. * if {@code capacity} is less than {@code c.size()}, or less
  142. * than 1.
  143. * @throws NullPointerException
  144. * if the specified collection or any of its elements are null
  145. */
  146. public ArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c) {
  147. this(capacity, fair);
  148.  
  149. final ReentrantLock lock = this.lock;
  150. lock.lock(); // Lock only for visibility, not mutual exclusion
  151. try {
  152. int i = 0;
  153. try {
  154. for (E e : c) {
  155. checkNotNull(e);
  156. items[i++] = e;
  157. }
  158. } catch (ArrayIndexOutOfBoundsException ex) {
  159. throw new IllegalArgumentException();
  160. }
  161. count = i;
  162. putIndex = (i == capacity) ? 0 : i;
  163. } finally {
  164. lock.unlock();
  165. }
  166. }
  167.  
  168. /**
  169. * Inserts the specified element at the tail of this queue if it is possible
  170. * to do so immediately without exceeding the queue's capacity, returning
  171. * {@code true} upon success and throwing an {@code IllegalStateException}
  172. * if this queue is full.
  173. *
  174. * @param e
  175. * the element to add
  176. * @return {@code true} (as specified by {@link Collection#add})
  177. * @throws IllegalStateException
  178. * if this queue is full
  179. * @throws NullPointerException
  180. * if the specified element is null
  181. */
  182. public boolean add(E e) {
  183. return super.add(e);
  184. }
  185.  
  186. /**
  187. * Inserts the specified element at the tail of this queue if it is possible
  188. * to do so immediately without exceeding the queue's capacity, returning
  189. * {@code true} upon success and {@code false} if this queue is full. This
  190. * method is generally preferable to method {@link #add}, which can fail to
  191. * insert an element only by throwing an exception.
  192. *
  193. * @throws NullPointerException
  194. * if the specified element is null
  195. */
  196. public boolean offer(E e) {
  197. checkNotNull(e);
  198. final ReentrantLock lock = this.lock;
  199. lock.lock();
  200. try {
  201. if (count == items.length)
  202. return false;
  203. else {
  204. insert(e);
  205. return true;
  206. }
  207. } finally {
  208. lock.unlock();
  209. }
  210. }
  211.  
  212. /**
  213. * Inserts the specified element at the tail of this queue, waiting up to
  214. * the specified wait time for space to become available if the queue is
  215. * full.
  216. *
  217. * @throws InterruptedException
  218. * {@inheritDoc}
  219. * @throws NullPointerException
  220. * {@inheritDoc}
  221. */
  222. public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {
  223.  
  224. checkNotNull(e);
  225. long nanos = unit.toNanos(timeout);
  226. final ReentrantLock lock = this.lock;
  227. lock.lockInterruptibly();
  228. try {
  229. while (count == items.length) {
  230. if (nanos <= 0)
  231. return false;
  232. nanos = notFull.awaitNanos(nanos);
  233. }
  234. insert(e);
  235. return true;
  236. } finally {
  237. lock.unlock();
  238. }
  239. }
  240.  
  241. public E poll() {
  242. final ReentrantLock lock = this.lock;
  243. lock.lock();
  244. try {
  245. return (count == 0) ? null : extract();
  246. } finally {
  247. lock.unlock();
  248. }
  249. }
  250.  
  251. public E poll(long timeout, TimeUnit unit) throws InterruptedException {
  252. long nanos = unit.toNanos(timeout);
  253. final ReentrantLock lock = this.lock;
  254. lock.lockInterruptibly();
  255. try {
  256. while (count == 0) {
  257. if (nanos <= 0)
  258. return null;
  259. nanos = notEmpty.awaitNanos(nanos);
  260. }
  261. return extract();
  262. } finally {
  263. lock.unlock();
  264. }
  265. }
  266.  
  267. public E peek() {
  268. final ReentrantLock lock = this.lock;
  269. lock.lock();
  270. try {
  271. return (count == 0) ? null : itemAt(takeIndex);
  272. } finally {
  273. lock.unlock();
  274. }
  275. }
  276.  
  277. // this doc comment is overridden to remove the reference to collections
  278. // greater in size than Integer.MAX_VALUE
  279. /**
  280. * Returns the number of elements in this queue.
  281. *
  282. * @return the number of elements in this queue
  283. */
  284. public int size() {
  285. final ReentrantLock lock = this.lock;
  286. lock.lock();
  287. try {
  288. return count;
  289. } finally {
  290. lock.unlock();
  291. }
  292. }
  293.  
  294. // this doc comment is a modified copy of the inherited doc comment,
  295. // without the reference to unlimited queues.
  296. /**
  297. * Returns the number of additional elements that this queue can ideally (in
  298. * the absence of memory or resource constraints) accept without blocking.
  299. * This is always equal to the initial capacity of this queue less the
  300. * current {@code size} of this queue.
  301. *
  302. * <p>
  303. * Note that you <em>cannot</em> always tell if an attempt to insert an
  304. * element will succeed by inspecting {@code remainingCapacity} because it
  305. * may be the case that another thread is about to insert or remove an
  306. * element.
  307. */
  308. public int remainingCapacity() {
  309. final ReentrantLock lock = this.lock;
  310. lock.lock();
  311. try {
  312. return items.length - count;
  313. } finally {
  314. lock.unlock();
  315. }
  316. }
  317.  
  318. /**
  319. * Removes a single instance of the specified element from this queue, if it
  320. * is present. More formally, removes an element {@code e} such that
  321. * {@code o.equals(e)}, if this queue contains one or more such elements.
  322. * Returns {@code true} if this queue contained the specified element (or
  323. * equivalently, if this queue changed as a result of the call).
  324. *
  325. * <p>
  326. * Removal of interior elements in circular array based queues is an
  327. * intrinsically slow and disruptive operation, so should be undertaken only
  328. * in exceptional circumstances, ideally only when the queue is known not to
  329. * be accessible by other threads.
  330. *
  331. * @param o
  332. * element to be removed from this queue, if present
  333. * @return {@code true} if this queue changed as a result of the call
  334. */
  335. public boolean remove(Object o) {
  336. if (o == null)
  337. return false;
  338. final Object[] items = this.items;
  339. final ReentrantLock lock = this.lock;
  340. lock.lock();
  341. try {
  342. for (int i = takeIndex, k = count; k > 0; i = inc(i), k--) {
  343. if (o.equals(items[i])) {
  344. removeAt(i);
  345. return true;
  346. }
  347. }
  348. return false;
  349. } finally {
  350. lock.unlock();
  351. }
  352. }
  353.  
  354. /**
  355. * Returns {@code true} if this queue contains the specified element. More
  356. * formally, returns {@code true} if and only if this queue contains at
  357. * least one element {@code e} such that {@code o.equals(e)}.
  358. *
  359. * @param o
  360. * object to be checked for containment in this queue
  361. * @return {@code true} if this queue contains the specified element
  362. */
  363. public boolean contains(Object o) {
  364. if (o == null)
  365. return false;
  366. final Object[] items = this.items;
  367. final ReentrantLock lock = this.lock;
  368. lock.lock();
  369. try {
  370. for (int i = takeIndex, k = count; k > 0; i = inc(i), k--)
  371. if (o.equals(items[i]))
  372. return true;
  373. return false;
  374. } finally {
  375. lock.unlock();
  376. }
  377. }
  378.  
  379. /**
  380. * Returns an array containing all of the elements in this queue, in proper
  381. * sequence.
  382. *
  383. * <p>
  384. * The returned array will be "safe" in that no references to it are
  385. * maintained by this queue. (In other words, this method must allocate a
  386. * new array). The caller is thus free to modify the returned array.
  387. *
  388. * <p>
  389. * This method acts as bridge between array-based and collection-based APIs.
  390. *
  391. * @return an array containing all of the elements in this queue
  392. */
  393. public Object[] toArray() {
  394. final Object[] items = this.items;
  395. final ReentrantLock lock = this.lock;
  396. lock.lock();
  397. try {
  398. final int count = this.count;
  399. Object[] a = new Object[count];
  400. for (int i = takeIndex, k = 0; k < count; i = inc(i), k++)
  401. a[k] = items[i];
  402. return a;
  403. } finally {
  404. lock.unlock();
  405. }
  406. }
  407.  
  408. /**
  409. * Returns an array containing all of the elements in this queue, in proper
  410. * sequence; the runtime type of the returned array is that of the specified
  411. * array. If the queue fits in the specified array, it is returned therein.
  412. * Otherwise, a new array is allocated with the runtime type of the
  413. * specified array and the size of this queue.
  414. *
  415. * <p>
  416. * If this queue fits in the specified array with room to spare (i.e., the
  417. * array has more elements than this queue), the element in the array
  418. * immediately following the end of the queue is set to {@code null}.
  419. *
  420. * <p>
  421. * Like the {@link #toArray()} method, this method acts as bridge between
  422. * array-based and collection-based APIs. Further, this method allows
  423. * precise control over the runtime type of the output array, and may, under
  424. * certain circumstances, be used to save allocation costs.
  425. *
  426. * <p>
  427. * Suppose {@code x} is a queue known to contain only strings. The following
  428. * code can be used to dump the queue into a newly allocated array of
  429. * {@code String}:
  430. *
  431. * <pre>
  432. * String[] y = x.toArray(new String[0]);
  433. * </pre>
  434. *
  435. * Note that {@code toArray(new Object[0])} is identical in function to
  436. * {@code toArray()}.
  437. *
  438. * @param a
  439. * the array into which the elements of the queue are to be
  440. * stored, if it is big enough; otherwise, a new array of the
  441. * same runtime type is allocated for this purpose
  442. * @return an array containing all of the elements in this queue
  443. * @throws ArrayStoreException
  444. * if the runtime type of the specified array is not a supertype
  445. * of the runtime type of every element in this queue
  446. * @throws NullPointerException
  447. * if the specified array is null
  448. */
  449. @SuppressWarnings("unchecked")
  450. public <T> T[] toArray(T[] a) {
  451. final Object[] items = this.items;
  452. final ReentrantLock lock = this.lock;
  453. lock.lock();
  454. try {
  455. final int count = this.count;
  456. final int len = a.length;
  457. if (len < count)
  458. a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), count);
  459. for (int i = takeIndex, k = 0; k < count; i = inc(i), k++)
  460. a[k] = (T) items[i];
  461. if (len > count)
  462. a[count] = null;
  463. return a;
  464. } finally {
  465. lock.unlock();
  466. }
  467. }
  468.  
  469. public String toString() {
  470. final ReentrantLock lock = this.lock;
  471. lock.lock();
  472. try {
  473. int k = count;
  474. if (k == 0)
  475. return "[]";
  476.  
  477. StringBuilder sb = new StringBuilder();
  478. sb.append('[');
  479. for (int i = takeIndex;; i = inc(i)) {
  480. Object e = items[i];
  481. sb.append(e == this ? "(this Collection)" : e);
  482. if (--k == 0)
  483. return sb.append(']').toString();
  484. sb.append(',').append(' ');
  485. }
  486. } finally {
  487. lock.unlock();
  488. }
  489. }
  490.  
  491. /**
  492. * Atomically removes all of the elements from this queue. The queue will be
  493. * empty after this call returns.
  494. */
  495. public void clear() {
  496. final Object[] items = this.items;
  497. final ReentrantLock lock = this.lock;
  498. lock.lock();
  499. try {
  500. for (int i = takeIndex, k = count; k > 0; i = inc(i), k--)
  501. items[i] = null;
  502. count = 0;
  503. putIndex = 0;
  504. takeIndex = 0;
  505. notFull.signalAll();
  506. } finally {
  507. lock.unlock();
  508. }
  509. }
  510.  
  511. /**
  512. * @throws UnsupportedOperationException
  513. * {@inheritDoc}
  514. * @throws ClassCastException
  515. * {@inheritDoc}
  516. * @throws NullPointerException
  517. * {@inheritDoc}
  518. * @throws IllegalArgumentException
  519. * {@inheritDoc}
  520. */
  521. public int drainTo(Collection<? super E> c) {
  522. checkNotNull(c);
  523. if (c == this)
  524. throw new IllegalArgumentException();
  525. final Object[] items = this.items;
  526. final ReentrantLock lock = this.lock;
  527. lock.lock();
  528. try {
  529. int i = takeIndex;
  530. int n = 0;
  531. int max = count;
  532. while (n < max) {
  533. c.add(this.<E>cast(items[i]));
  534. items[i] = null;
  535. i = inc(i);
  536. ++n;
  537. }
  538. if (n > 0) {
  539. count = 0;
  540. putIndex = 0;
  541. takeIndex = 0;
  542. notFull.signalAll();
  543. }
  544. return n;
  545. } finally {
  546. lock.unlock();
  547. }
  548. }
  549.  
  550. /**
  551. * @throws UnsupportedOperationException
  552. * {@inheritDoc}
  553. * @throws ClassCastException
  554. * {@inheritDoc}
  555. * @throws NullPointerException
  556. * {@inheritDoc}
  557. * @throws IllegalArgumentException
  558. * {@inheritDoc}
  559. */
  560. public int drainTo(Collection<? super E> c, int maxElements) {
  561. checkNotNull(c);
  562. if (c == this)
  563. throw new IllegalArgumentException();
  564. if (maxElements <= 0)
  565. return 0;
  566. final Object[] items = this.items;
  567. final ReentrantLock lock = this.lock;
  568. lock.lock();
  569. try {
  570. int i = takeIndex;
  571. int n = 0;
  572. int max = (maxElements < count) ? maxElements : count;
  573. while (n < max) {
  574. c.add(this.<E>cast(items[i]));
  575. items[i] = null;
  576. i = inc(i);
  577. ++n;
  578. }
  579. if (n > 0) {
  580. count -= n;
  581. takeIndex = i;
  582. notFull.signalAll();
  583. }
  584. return n;
  585. } finally {
  586. lock.unlock();
  587. }
  588. }
  589.  
  590. /**
  591. * Returns an iterator over the elements in this queue in proper sequence.
  592. * The elements will be returned in order from first (head) to last (tail).
  593. *
  594. * <p>
  595. * The returned {@code Iterator} is a "weakly consistent" iterator that will
  596. * never throw {@link java.util.ConcurrentModificationException
  597. * ConcurrentModificationException}, and guarantees to traverse elements as
  598. * they existed upon construction of the iterator, and may (but is not
  599. * guaranteed to) reflect any modifications subsequent to construction.
  600. *
  601. * @return an iterator over the elements in this queue in proper sequence
  602. */
  603. public Iterator<E> iterator() {
  604. return new Itr();
  605. }
  606.  
  607. /**
  608. * 重点分析方法:
  609. *
  610. * @return
  611. * @throws InterruptedException
  612. */
  613. public E take() throws InterruptedException {
  614. final ReentrantLock lock = this.lock;
  615. lock.lockInterruptibly();
  616. try {
  617. //解决伪唤醒
  618. while (count == 0)
  619. notEmpty.await();//如果缓冲区为空的话,则阻塞
  620. return extract();
  621. } finally {
  622. //释放锁
  623. lock.unlock();
  624. }
  625. }
  626.  
  627. /**
  628. * Extracts element at current take position, advances, and signals. Call
  629. * only when holding lock.
  630. */
  631. private E extract() {
  632. final Object[] items = this.items;
  633. //takeIndexe为消费数据
  634. E x = this.<E>cast(items[takeIndex]);
  635. items[takeIndex] = null;
  636. // 计算下一个消费数据的位置
  637. takeIndex = inc(takeIndex);
  638. --count;
  639. //通知生产者生产数据
  640. notFull.signal();
  641. return x;
  642. }
  643.  
  644. // Internal helper methods
  645. /**
  646. * Circularly increment i.
  647. */
  648. final int inc(int i) {
  649. return (++i == items.length) ? 0 : i;
  650. }
  651.  
  652. /**
  653. * 重点分析方法:
  654. *
  655. * Inserts the specified element at the tail of this queue, waiting for
  656. * space to become available if the queue is full.
  657. *
  658. * @throws InterruptedException
  659. * {@inheritDoc}
  660. * @throws NullPointerException
  661. * {@inheritDoc}
  662. */
  663. public void put(E e) throws InterruptedException {
  664. checkNotNull(e);
  665. final ReentrantLock lock = this.lock;
  666. lock.lockInterruptibly();
  667. try {
  668. //解决伪唤醒
  669. while (count == items.length)
  670. notFull.await();//如果容器满了则阻塞此处
  671. insert(e);
  672. } finally {
  673. // 释放锁
  674. lock.unlock();
  675. }
  676. }
  677.  
  678. /**
  679. * Inserts element at current put position, advances, and signals. Call only
  680. * when holding lock.
  681. */
  682. private void insert(E x) {
  683. items[putIndex] = x;
  684. putIndex = inc(putIndex);
  685. ++count;
  686. //唤醒消费者进行消费
  687. notEmpty.signal();
  688. }
  689.  
  690. /**
  691. * Iterator for ArrayBlockingQueue. To maintain weak consistency with
  692. * respect to puts and takes, we (1) read ahead one slot, so as to not
  693. * report hasNext true but then not have an element to return -- however we
  694. * later recheck this slot to use the most current value; (2) ensure that
  695. * each array slot is traversed at most once (by tracking "remaining"
  696. * elements); (3) skip over null slots, which can occur if takes race ahead
  697. * of iterators. However, for circular array-based queues, we cannot rely on
  698. * any well established definition of what it means to be weakly consistent
  699. * with respect to interior removes since these may require slot overwrites
  700. * in the process of sliding elements to cover gaps. So we settle for
  701. * resiliency, operating on established apparent nexts, which may miss some
  702. * elements that have moved between calls to next.
  703. */
  704. private class Itr implements Iterator<E> {
  705. private int remaining; // Number of elements yet to be returned
  706. private int nextIndex; // Index of element to be returned by next
  707. private E nextItem; // Element to be returned by next call to next
  708. private E lastItem; // Element returned by last call to next
  709. private int lastRet; // Index of last element returned, or -1 if none
  710.  
  711. Itr() {
  712. final ReentrantLock lock = ArrayBlockingQueue.this.lock;
  713. lock.lock();
  714. try {
  715. lastRet = -1;
  716. if ((remaining = count) > 0)
  717. nextItem = itemAt(nextIndex = takeIndex);
  718. } finally {
  719. lock.unlock();
  720. }
  721. }
  722.  
  723. public boolean hasNext() {
  724. return remaining > 0;
  725. }
  726.  
  727. public E next() {
  728. final ReentrantLock lock = ArrayBlockingQueue.this.lock;
  729. lock.lock();
  730. try {
  731. if (remaining <= 0)
  732. throw new NoSuchElementException();
  733. lastRet = nextIndex;
  734. E x = itemAt(nextIndex); // check for fresher value
  735. if (x == null) {
  736. x = nextItem; // we are forced to report old value
  737. lastItem = null; // but ensure remove fails
  738. } else
  739. lastItem = x;
  740. while (--remaining > 0 && // skip over nulls
  741. (nextItem = itemAt(nextIndex = inc(nextIndex))) == null)
  742. ;
  743. return x;
  744. } finally {
  745. lock.unlock();
  746. }
  747. }
  748.  
  749. public void remove() {
  750. final ReentrantLock lock = ArrayBlockingQueue.this.lock;
  751. lock.lock();
  752. try {
  753. int i = lastRet;
  754. if (i == -1)
  755. throw new IllegalStateException();
  756. lastRet = -1;
  757. E x = lastItem;
  758. lastItem = null;
  759. // only remove if item still at index
  760. if (x != null && x == items[i]) {
  761. boolean removingHead = (i == takeIndex);
  762. removeAt(i);
  763. if (!removingHead)
  764. nextIndex = dec(nextIndex);
  765. }
  766. } finally {
  767. lock.unlock();
  768. }
  769. }
  770.  
  771. }
  772.  
  773. }

Lock和Condition在JDK中ArrayBlockingQueue的应用的更多相关文章

  1. Lock和Condition在JDK中LinkedBlockingQueue的应用

    Lock和Condition在JDK中LinkedBlockingQueue的应用,核心源码注释解析如下: import java.util.concurrent.LinkedBlockingQueu ...

  2. Java中的线程--Lock和Condition实现线程同步通信

    随着学习的深入,我接触了更多之前没有接触到的知识,对线程间的同步通信有了更多的认识,之前已经学习过synchronized 实现线程间同步通信,今天来学习更多的--Lock,GO!!! 一.初时Loc ...

  3. 线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯

    1.Lock相关知识介绍 好比我同时种了几块地的麦子,然后就等待收割.收割时,则是哪块先熟了,先收割哪块. 下面举一个面试题的例子来引出Lock缓存读写锁的案例,一个load()和get()方法返回值 ...

  4. 【Java线程】Lock、Condition

    http://www.infoq.com/cn/articles/java-memory-model-5  深入理解Java内存模型(五)——锁 http://www.ibm.com/develope ...

  5. 【Java线程】锁机制:synchronized、Lock、Condition

    http://www.infoq.com/cn/articles/java-memory-model-5  深入理解Java内存模型(五)——锁 http://www.ibm.com/develope ...

  6. Java并发(10)- 简单聊聊JDK中的七大阻塞队列

    引言 JDK中除了上文提到的各种并发容器,还提供了丰富的阻塞队列.阻塞队列统一实现了BlockingQueue接口,BlockingQueue接口在java.util包Queue接口的基础上提供了pu ...

  7. Lock和Condition

    1 什么是可重入锁 可重入锁是说一个线程在已经获取了该锁的情况下,还可以再次获取该锁. 主要的应用场景: 可重入锁指的是在一个线程中可以多次获取同一把锁,比如:一个线程在执行一个带锁的方法,该方法中又 ...

  8. 【Java线程】锁机制:synchronized、Lock、Condition(转)

    原文地址 1.synchronized 把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性(atomicity)和 可见性(visibility). 1.1 原子性 ...

  9. 并发之lock的condition接口

    13.死磕Java并发-----J.U.C之Condition 12.Condition使用总结 11.Java并发编程系列之十七:Condition接口 === 13.死磕Java并发-----J. ...

随机推荐

  1. JavaScript 深入之从原型到原型链

    1 .构造函数创建对象 我们先使用构造函数创建一个对象: function Person(){ } var p = new Person(); p.name = 'ccy'; console.log( ...

  2. MySQL事务笔记

    1.结束事务的方法用什么? 2.事务的最终形态是什么? commit 提交 rollback 回滚 3.事务的四大特征? ⑴ 原子性 一个事务是最小的工作单元,事务包含的所有操作要么全部成功,要么全部 ...

  3. RockChip RK3326 系统编译问题总结

    1. 序言 本文主要记录了RK3326平台系统编译过程中遇到的各种问题,并加以解决! 环境: 宿主Linux:Ubuntu 16.04 目标机:RK3326 (64bit) Toolchain:gcc ...

  4. 运行 svgatest 显示 mmap /dev/zero Permission denied 解决办法

    答案是我在这个网站上找到的: 执行 xset dpms force off 命令就可以解决掉这个问题. 再次运行 svgatest 程序,得到了预期的结果,perfect!

  5. swiper下滑分页,减少swiper-slide项的时候会出现空白

    修改子项后,先重置当前的页,调用 swiper.slideTo(0); 滚动到初始位置 再调用 swiper.update(); 更新一系列设置就可以了.

  6. NLog基础配置

    <?xml version="1.0" encoding="utf-8" ?> <nlog xmlns="http://www.nl ...

  7. 菜鸟入门【ASP.NET Core】8:Middleware管道介绍、自己动手构建RequestDelegate管道

    中间件:是汇集到以处理请求和响应的一个应用程序管道的软件. 每个组件: 可以选择是否要将请求传递到管道中的下一个组件. 之前和之后调用管道中的下一个组件,可以执行工作. 使用请求委托来生成请求管道.  ...

  8. groovy使用范型的坑

    java的范型 Map<String, Integer> map = new HashMap<>(); map.put("a", 100); map.put ...

  9. TestOps - 最健壮性的测试角色

    一十一 发表于 2018-03-02 09:10:08 TestOps   最具影响力的测试运维一体化综合平台. DevOps实现了从代码到服务的快速落地,而TestOps集成了DevOps效率,更是 ...

  10. C# 特性学习笔记

    1.自己定义的特性 注意注释!!!!! 2.使用特性 3.特性的用处