1、生產者消費者案例oop
1.使用synchronized關鍵字實現this
1 public class TestProductorAndConsumer { 2 public static void main(String[] args) { 3 Clerk clerk = new Clerk(); 4 Productor pro = new Productor(clerk); 5 Consumer cus = new Consumer(clerk); 6
7 new Thread(pro, "生產者 A").start(); 8 new Thread(cus, "消費者 B").start(); 9 new Thread(pro, "生產者 C").start(); 10 new Thread(cus, "消費者 D").start(); 11 } 12 } 13 //店員
14 class Clerk{ 15 private int product = 0; 16 //進貨
17 public synchronized void get(){ //循環次數:0
18 while(product >= 1){ 19 System.out.println("產品已滿!"); 20 try { 21 this.wait(); //爲了不虛假喚醒問題,wait應該老是使用在循環中
22 } catch (InterruptedException e) { 23 } 24 } 25 System.out.println(Thread.currentThread().getName() + " : " + ++product); 26 this.notifyAll(); 27 } 28 //賣貨
29 public synchronized void sale(){ //product = 0; 循環次數:0
30 while(product <= 0){ 31 System.out.println("缺貨!"); 32 try { 33 this.wait(); 34 } catch (InterruptedException e) { 35 } 36 } 37 System.out.println(Thread.currentThread().getName() + " : " + --product); 38 this.notifyAll(); 39 } 40 } 41 //生產者
42 class Productor implements Runnable{ 43 private Clerk clerk; 44 public Productor(Clerk clerk) { 45 this.clerk = clerk; 46 } 47 public void run() { 48 for (int i = 0; i < 20; i++) { 49 try { 50 Thread.sleep(200); 51 } catch (InterruptedException e) { 52 } 53 clerk.get(); 54 } 55 } 56 } 57 //消費者
58 class Consumer implements Runnable{ 59 private Clerk clerk; 60 public Consumer(Clerk clerk) { 61 this.clerk = clerk; 62 } 63 public void run() { 64 for (int i = 0; i < 20; i++) { 65 clerk.sale(); 66 } 67 } 68 }
2.使用Lock同步鎖和Condition類實現spa
1 public class TestProductorAndConsumerForLock { 2 public static void main(String[] args) { 3 Clerk clerk = new Clerk(); 4 Productor pro = new Productor(clerk); 5 Consumer con = new Consumer(clerk); 6
7 new Thread(pro, "生產者 A").start(); 8 new Thread(con, "消費者 B").start(); 9 // new Thread(pro, "生產者 C").start(); 10 // new Thread(con, "消費者 D").start();
11 } 12 } 13 class Clerk { 14 private int product = 0; 15 private Lock lock = new ReentrantLock(); 16 private Condition condition = lock.newCondition(); 17 // 進貨
18 public void get() { 19 lock.lock(); 20 try { 21 if (product >= 1) { // 爲了不虛假喚醒,應該老是使用在循環中。
22 System.out.println("產品已滿!"); 23 try { 24 condition.await(); 25 } catch (InterruptedException e) { 26 } 27 } 28 System.out.println(Thread.currentThread().getName() + " : "+ ++product); 29 condition.signalAll(); 30 } finally { 31 lock.unlock(); 32 } 33 } 34 // 賣貨
35 public void sale() { 36 lock.lock(); 37 try { 38 if (product <= 0) { 39 System.out.println("缺貨!"); 40 try { 41 condition.await(); 42 } catch (InterruptedException e) { 43 } 44 } 45 System.out.println(Thread.currentThread().getName() + " : "+ --product); 46 condition.signalAll(); 47 } finally { 48 lock.unlock(); 49 } 50 } 51 } 52
53 // 生產者
54 class Productor implements Runnable { 55 private Clerk clerk; 56 public Productor(Clerk clerk) { 57 this.clerk = clerk; 58 } 59 public void run() { 60 for (int i = 0; i < 20; i++) { 61 try { 62 Thread.sleep(200); 63 } catch (InterruptedException e) { 64 e.printStackTrace(); 65 } 66 clerk.get(); 67 } 68 } 69 } 70
71 // 消費者
72 class Consumer implements Runnable { 73 private Clerk clerk; 74 public Consumer(Clerk clerk) { 75 this.clerk = clerk; 76 } 77 public void run() { 78 for (int i = 0; i < 20; i++) { 79 clerk.sale(); 80 } 81 } 82 }
2、線程按序交替線程
編寫一個程序,開啓3個線程,這三個線程的ID分別爲A、B、C,每一個線程將本身的ID在屏幕上打印10遍,要求輸出的結果必須按順序顯示。如:ABCABC......依次遞歸。code
1 public class TestABCAlternate { 2 public static void main(String[] args) { 3 AlternateDemo ad = new AlternateDemo(); 4 new Thread(new Runnable() { 5 public void run() { 6 for (int i = 1; i <= 10; i++) { 7 ad.loopA(i); 8 } 9 } 10 }, "A").start(); 11 new Thread(new Runnable() { 12 public void run() { 13 for (int i = 1; i <= 10; i++) { 14 ad.loopB(i); 15 } 16 } 17 }, "B").start(); 18 new Thread(new Runnable() { 19 public void run() { 20 for (int i = 1; i <= 10; i++) { 21 ad.loopC(i); 22 System.out.println("-----------------------------------"); 23 } 24 } 25 }, "C").start(); 26 } 27 } 28
29 class AlternateDemo{ 30 private int number = 1; //當前正在執行線程的標記
31 private Lock lock = new ReentrantLock(); 32 private Condition condition1 = lock.newCondition(); 33 private Condition condition2 = lock.newCondition(); 34 private Condition condition3 = lock.newCondition(); 35
36 public void loopA(int totalLoop){ //totalLoop : 循環第幾輪
37 lock.lock(); 38 try { 39 if(number != 1){ //1. 判斷
40 condition1.await(); 41 } 42 //2. 打印
43 for (int i = 1; i <= 1; i++) { 44 System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop); 45 } 46 //3. 喚醒
47 number = 2; 48 condition2.signal(); 49 } catch (Exception e) { 50 e.printStackTrace(); 51 } finally { 52 lock.unlock(); 53 } 54 } 55 public void loopB(int totalLoop){ 56 lock.lock(); 57 try { 58 if(number != 2){ //1. 判斷
59 condition2.await(); 60 } 61 //2. 打印
62 for (int i = 1; i <= 1; i++) { 63 System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop); 64 } 65 //3. 喚醒
66 number = 3; 67 condition3.signal(); 68 } catch (Exception e) { 69 e.printStackTrace(); 70 } finally { 71 lock.unlock(); 72 } 73 } 74 public void loopC(int totalLoop){ 75 lock.lock(); 76 try { 77 if(number != 3){ //1. 判斷
78 condition3.await(); 79 } 80 //2. 打印
81 for (int i = 1; i <= 1; i++) { 82 System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop); 83 } 84 //3. 喚醒
85 number = 1; 86 condition1.signal(); 87 } catch (Exception e) { 88 e.printStackTrace(); 89 } finally { 90 lock.unlock(); 91 } 92 } 93 }