多執行緒實現通訊
阿新 • • 發佈:2018-11-26
多執行緒實現通訊
我們來做個簡單的多執行緒之間的通訊機制,比如有兩個執行緒,一個執行緒傳送資料,一個執行緒接受。而讓這兩個執行緒
有順序的執行,不僅要對共享資源上鎖,還要用到訊號量來實現傳送和接受交替。
看下程式碼實現:
package Test; public class LockBuffer { private int value; private boolean isEmpty=true; public synchronized void put(int i) { while(!this.isEmpty) try {this.wait();} catch (InterruptedException ex) { } this.value=i; this.isEmpty=false; this.notify(); } public synchronized int get() { while(this.isEmpty) try {this.wait();} catch(InterruptedException ex) {} this.isEmpty=true; this.notify(); return this.value; } public static void main(String args[]) { LockBuffer buffer= new LockBuffer(); (new SendThread(buffer)).start(); (new ReceiveThread(buffer)).start(); } } class SendThread extends Thread{ private LockBuffer buffer; public SendThread(LockBuffer buffer) { this.buffer=buffer; } public void run() { for(int i=1;i<5;i++) { buffer.put(i); System.out.println(this.getClass().getName()+"put:"+i); try { this.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } class ReceiveThread extends Thread{ private LockBuffer buffer; public ReceiveThread(LockBuffer buffer) { this.buffer=buffer; } public void run() { for(int i=1;i<5;i++) { System.out.println(this.getClass().getName()+"get:"+buffer.get()); try { this.sleep(10); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
我們對get和put方法上鎖,這樣保證同一時間只有一個執行緒來實現對共享資源value的讀或者寫。而isEmpty訊號量來
保證先執行寫執行緒後執行讀執行緒。加入讀執行緒先執行,當到 while(this.isEmpty) try {this.wait();}執行緒就會wait阻塞自
己的執行緒。進入waitting態。然後寫執行緒先寫,寫完之後改變isEmpty的值。喚醒讀執行緒。這時候寫執行緒不能繼續寫。
因為isEmpty的值變化了。在執行寫會執行wait,進入waitting態。這時候他只能等讀執行緒讀完了才能繼續寫。
這樣就實現了讀寫讀寫讀寫。
注意:在控制檯輸出的時候可能會出現先receive後send的情況,這並不是說讀執行在了寫的前面。而是因為編譯器
在控制檯輸出的速度遠遠趕不上執行緒運算和切換執行緒的速度,所以可能會出現先讀後寫的情況。