1. 程式人生 > 其它 >多執行緒-執行緒間通訊-多生產者多消費者問題(JDK1.5後Lock,Condition解決辦法及開發中程式碼範例)

多執行緒-執行緒間通訊-多生產者多消費者問題(JDK1.5後Lock,Condition解決辦法及開發中程式碼範例)

  1 package multithread4;
  2 
  3 import java.util.concurrent.locks.Condition;
  4 import java.util.concurrent.locks.Lock;
  5 import java.util.concurrent.locks.ReentrantLock;
  6 
  7 /*同步程式碼塊對於鎖的操作是隱式的
  8  * 
  9  * jdk1.5以後將同步和鎖封裝成了物件。
 10  * 並將操作鎖的隱式方式定義到了該物件中,將隱式動作變成了顯示動作 
 11  * 
 12  * 
 13  * Lock介面:出現替代了同步程式碼塊或者同步函式。將同步的隱式鎖操作變成顯式鎖操作
14 * 同時更為靈活,可以一個鎖上加上多組監視器。 15 * lock():獲取鎖 16 * unlock():釋放鎖,通常需要定義finally程式碼塊中。 17 * 18 * Condition介面:出現替代了Object中的wait notify notifyAll方法。 19 * 將這些監視器方法單獨進行了封裝,變成Conditon監視器物件。 20 * 可以與任意鎖進行組合 21 * await(); 22 * signal(); 23 * signalAll(); 24 *
25 */ 26 27 28 /* 29 * 生產者,消費者。 30 * 31 * 多生產者,多消費者的問題。 32 * 33 * if判斷標記,只有一次,會導致不該執行的執行緒運行了。出現了資料錯誤的情況。 34 * while判斷標記,解決了執行緒獲取執行權後,是否要執行! 35 * 36 * notify:只能喚醒一個執行緒,如果本方喚醒了本方,沒有意義。而且while判斷標記+notify會產生死鎖 37 * notifyAll解決了,本方執行緒一定會喚醒對方執行緒 38 * 39 * 死鎖 四個執行緒都等待沒有被喚醒也是一種情況,懸掛
40 */ 41 42 class Resource2{ 43 private String name; 44 private int count = 1; 45 private boolean flag = false; 46 //建立一個鎖物件 47 Lock lock = new ReentrantLock(); 48 //通過已有的鎖獲取該鎖上的監視器物件。 49 // Condition con = lock.newCondition(); 50 51 //通過已有的鎖獲取兩組監視器,一組監視生產者,一組監視消費者。 用lock condition解決辦法 52 Condition producer_con = lock.newCondition(); 53 Condition consumer_con = lock.newCondition(); 54 55 public void set(String name) { 56 lock.lock(); 57 try { 58 /*if*/ while (flag) { 59 try { 60 // lock.wait(); 61 // con.await(); 62 producer_con.await(); 63 } catch (InterruptedException e) { 64 65 } 66 } 67 this.name = name + count; 68 count++; 69 System.out.println(Thread.currentThread().getName()+"..生產者.."+this.name); 70 flag = true; 71 // notify(); 72 // notifyAll(); 73 // con.signalAll(); 74 consumer_con.signal(); 75 } finally { 76 lock.unlock(); 77 } 78 79 } 80 public void out() { 81 lock.lock(); 82 try { 83 /*if*/ while (!flag) { 84 try { 85 // con.await(); 86 consumer_con.await(); 87 } catch (InterruptedException e) { 88 89 } 90 } 91 System.out.println(Thread.currentThread().getName()+"..消費者......"+this.name); 92 flag = false; 93 // notify(); 94 // notifyAll();//為了解決死鎖 將其餘三個都喚醒 95 // con.signalAll(); 96 producer_con.signal(); 97 } finally { 98 lock.unlock(); 99 } 100 101 } 102 103 class Producer implements Runnable{ 104 private Resource2 r; 105 public Producer(Resource2 r) { 106 this.r = r; 107 } 108 public void run() { 109 while(true) { 110 r.set("烤鴨"); 111 } 112 } 113 } 114 class Consumer implements Runnable{ 115 private Resource2 r; 116 public Consumer(Resource2 r) { 117 this.r = r; 118 } 119 public void run() { 120 while(true) { 121 r.out(); 122 } 123 } 124 } 125 public class ProducerConsumerDemo2 { 126 127 public static void main(String[] args) { 128 129 Resource2 r = new Resource2(); 130 Producer pro = new Producer(r); 131 Consumer con = new Consumer(r); 132 133 Thread t0 = new Thread(pro); 134 Thread t1 = new Thread(pro); 135 Thread t2 = new Thread(con); 136 Thread t3 = new Thread(con); 137 138 t0.start(); 139 t1.start(); 140 t2.start(); 141 t3.start(); 142 } 143 144 }
ProducerConsumerDemo2