자바 이론 과 실천: 비 차단 알고리즘 소개


  
  
  
  
  1. , , 。Java   synchronized  ( ), ,  synchronized  ,  synchronized  。 , , , , 。 
  2.  
  3.  “ ”  , , - - , 。  volatile  , , 。 
  4.  
  5.  
  6.  
  7.  1   Counter  , 。 , , : ,  1, 。(  getValue  ,  getValue  。 , 。) 
  8.  
  9. , , 。JVM  , 。 , 。 
  10.  
  11.  1.   
  12. public final class Counter { 
  13. private long value = 0; 
  14. public synchronized long getValue() { 
  15. return value; 
  16. } 
  17. public synchronized long increment() { 
  18. return ++value; 
  19. } 
  20. } 
  21.  
  22.  2   NonblockingCounter  :  AtomicInteger   compareAndSet() (CAS) 。compareAndSet()   “ , , ”(  “ ”   “ ”  。) 
  23.  
  24.  2.   CAS   
  25. public class NonblockingCounter { 
  26. private AtomicInteger value; 
  27. public int getValue() { 
  28. return value.get(); 
  29. } 
  30. public int increment() { 
  31. int v; 
  32. do { 
  33. v = value.get(); 
  34. while (!value.compareAndSet(v, v + 1)); 
  35. return v + 1; 
  36. } 
  37. } 
  38.  
  39. , , , 。 ,  20  ,  Java 5.0  ,  Java  。 
  40.  
  41. , , ,  compareAndSet()  。( ,  AtomicInteger  ,  compareAndSet(),  NonblockingCounter.increment())。 
  42.  
  43. 。 ,  JVM  , ( ) , , 。 , 。  CAS  , 。 
  44.  
  45. NonblockingCounter  ,  ——  ,  CAS  。 , 。 , 。 ,  ——  , 。 , , 。 
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  3   ConcurrentStack。ConcurrentStack   push()   pop()   NonblockingCounter  , ,  “ ”  , 。push()  , , , , 。  CAS  , , 。 
  52.  
  53.  3.   Treiber   
  54. public class ConcurrentStack<E> { 
  55. AtomicReference<Node<E>> head = new AtomicReference<Node<E>>(); 
  56. public void push(E item) { 
  57. Node<E> newHead = new Node<E>(item); 
  58. Node<E> oldHead; 
  59. do { 
  60. oldHead = head.get(); 
  61. newHead.next = oldHead; 
  62. } while (!head.compareAndSet(oldHead, newHead)); 
  63. } 
  64. public E pop() { 
  65. Node<E> oldHead; 
  66. Node<E> newHead; 
  67. do { 
  68. oldHead = head.get(); 
  69. if (oldHead == null) 
  70. return null; 
  71. newHead = oldHead.next; 
  72. } while (!head.compareAndSet(oldHead,newHead)); 
  73. return oldHead.item; 
  74. } 
  75. static class Node<E> { 
  76. final E item; 
  77. Node<E> next; 
  78. public Node(E item) { this.item = item; } 
  79. } 
  80. } 
  81.  
  82.  
  83.  
  84. , ,  CAS  , , 。  CAS  ( ,  CAS  ),  CAS  。 
  85.  
  86. ( ), , , , , 。 , , , , 。( , 。)“ ”  , , , 。 
  87.  
  88.  
  89.  
  90.  
  91.  
  92. ( ) ,  CAS, 。 , , 、 。CAS  , 。 , 、 , ,  CAS  , 。 
  93.  
  94. , :“ ”  ,“ ”  。 ,  CAS。  CAS  :  CAS  ,  CAS  , ?  CAS  , ? 
  95.  
  96. ,  “ ”  ( ), ,  AWOL, 。 ,  “ ”  , 。 , , ,  CAS  ( , )。 
  97.  
  98.  “ ”  , , 。 , , , 。 , , , , ( )。 
  99.  
  100.  4   LinkedQueue   Michael-Scott  ,  ConcurrentLinkedQueue  : 
  101.  
  102.  4. Michael-Scott   
  103. public class LinkedQueue <E> { 
  104. private static class Node <E> { 
  105. final E item; 
  106. final AtomicReference<Node<E>> next; 
  107. Node(E item, Node<E> next) { 
  108. this.item = item; 
  109. this.next = new AtomicReference<Node<E>>(next); 
  110. } 
  111. } 
  112. private AtomicReference<Node<E>> head 
  113. = new AtomicReference<Node<E>>(new Node<E>(null, null)); 
  114. private AtomicReference<Node<E>> tail = head; 
  115. public boolean put(E item) { 
  116. Node<E> newNode = new Node<E>(item, null); 
  117. while (true) { 
  118. Node<E> curTail = tail.get(); 
  119. Node<E> residue = curTail.next.get(); 
  120. if (curTail == tail.get()) { 
  121. if (residue == null) /* A */ { 
  122. if (curTail.next.compareAndSet(null, newNode)) /* C */ { 
  123. tail.compareAndSet(curTail, newNode) /* D */ ; 
  124. return true; 
  125. } 
  126. } else { 
  127. tail.compareAndSet(curTail, residue) /* B */; 
  128. } 
  129. } 
  130. } 
  131. } 
  132. } 
  133.  
  134. , 。 ; 。  1  : 
  135.  
  136.  1.  ,  
  137.  
  138.    4  , ,  CAS  : (C) , (D)。 , , , 。 , , 。 ,  “ ”, , 。 
  139.  
  140. : ( ,  1     3) (  2)。  CAS(D) , ;  CAS(C) , 。 ,  next   null, ,  null。  tail.next   null, ,  “ ”  。 
  141.  
  142.  2.  , ,  
  143.  
  144. (A) , ,    4  。 , , (C) (D) 。 ,  “ ”  , (B)。 , , , 。 
  145.  
  146.  CAS(C) ; , ,  CAS  。  CAS(D) ,  ——  (B) ! 
  147.  
  148.  3.  ,  
  149.  
  150.  
  151.  
  152.  JVM  , 。 ; , 。  Mustang(Java 6.0) ,  SynchronousQueue  。  SynchronousQueue,  Executors.newCachedThreadPool()  。 ,  3  。  Mustang  (  Dolphin) , 。 
  153.  
  154.  
  155.  
  156.  
  157.  
  158. 。 , 。  Java  , ,  Java  , 。 
  159.  
  160.  
  161.  
  162.  
  163.  developerWorks     。 
  164.  
  165. “ ” (developerWorks,Brian Goetz,2004   11  ):  Java 5.0  , - 。 
  166.  
  167. “Scalable Synchronous Queues”(ACM SIGPLAN  ,William N. Scherer III、Doug Lea   Michael L. Scott,2006   3  ):  Java 6   SynchronousQueue  。 
  168.  
  169. “Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queues”(Maged M. Michael   Michael L. Scott, ,1996):    4  。 
  170.  
  171. Java Concurrency in Practice (Addison-Wesley Professional,Brian Goetz、Tim Peierls、Joshua Bloch、Joseph Bowbeer、David Holmes   Doug Lea,2006   6  ):  Java   how-to  , , , 。 
  172.  
  173. Java  :  Java  。 
  174.  
  175.  
  176. JDK 5.0 Update 6:  JDK 5.0  。 
  177.  
  178.  
  179. 。 
  180.  
  181. developerWorks blog:  developerWorks  。 
  182.  
  183.  
  184.  
  185. Brian Goetz   18  。  Quiotix  , ,  Los Altos,  JCP  。Brian   Java Concurrency In Practice   2006   Addison-Wesley  。  Brian    。  

좋은 웹페이지 즐겨찾기