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


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

좋은 웹페이지 즐겨찾기