多執行緒併發包學習總結(一)Lock鎖
阿新 • • 發佈:2018-12-12
為什麼需要Lock鎖 1.因為我們需要有一種機制可以不讓等待的執行緒一直無期限地等待下去(比如只等待一定的時間或者能夠響應中斷),通過Lock就可以辦到。 2.通過Lock可以知道執行緒有沒有成功獲取到鎖 3.Lock鎖相當於汽車中的手動擋,相比synchronized更加靈活,輕巧和方便。 4.Lock可以提高多個執行緒進行讀操作的效率。 使用Lock和Condition來替代synchronized和wait(),nofity()來實現同步和程序通訊,程式碼如下 lock鎖的通用公式 Lock lock =new Lock(); Condition condition=new Condition try{ lock.lock;上鎖 if(flag){ try{ condition.await }catch(){ } } 業務邏輯處理 condition.single(); }catch(){
}finally { lock.unlock//釋放鎖 }
下面用一個具體的例子演示
package com.jerry.Thread; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; //共用資源 class Res { Lock lock=new ReentrantLock(); public String username; public String userSex; public boolean flag=false; } //寫入資源 class Out extends Thread { Res res; Condition condition;//用來程序通訊 public Out(Res res,Condition condition) { this.condition=condition; this.res = res; } public void run() { int count = 0; while (true) { try{ res.lock.lock();//開始上鎖 if(res.flag) { try { condition.await();//程序等待 } catch (Exception e) { e.printStackTrace(); } } if (count == 0) { res.username = "jerry"; res.userSex = "boy"; } else { res.username = "sina"; res.userSex = "girl"; } //求奇數偶數 count = (count + 1) % 2; res.flag=true; condition.signal();//喚醒程序 }catch (Exception ex){ ex.printStackTrace(); } finally { res.lock.unlock();//釋放鎖 } } } } //讀入操作 class Input extends Thread{ Res res; Condition condition; public Input(Res res,Condition condition) { this.condition=condition; this.res = res; } public void run() { while(true){ try { res.lock.lock(); if (!res.flag){ try { condition.await();//等待 }catch (Exception e){ e.printStackTrace(); } } System.out.println(res.username+","+res.userSex); res.flag=false; condition.signal();//喚醒程序 }catch (Exception ex){ ex.printStackTrace(); } finally { res.lock.unlock(); } } } } public class LockDemo{ public static void main(String[] args) { Res res =new Res(); Condition condition=res.lock.newCondition(); Out out=new Out(res,condition); Input input=new Input(res,condition); out.start(); input.start(); } }