歡迎您光臨本站 註冊首頁

Java Lock鎖多線程中實現流水線任務

←手機掃碼閱讀     ljg58026 @ 2020-05-02 , reply:0

下面程序代碼通過使用Lock鎖執行簡單的流水線任務:
import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @author lzq * @data 2020/4/29 0029 - 下午 9:48 */ public class TestLock { public static void main(String[] args) { DataSource dataSource=new DataSource(); new Thread(() -> { for (int i=0;i<10;i++){ new="" -="">{ for (int i=0;i<10;i++){ new="" -="">{ for (int i=0;i<10;i++){ dataSource.c(); } },"C").start(); } } class DataSource{ private int x=1; private Lock lock=new ReentrantLock(); private Condition condition1=lock.newCondition(); private Condition condition2=lock.newCondition(); private Condition condition3=lock.newCondition(); public void a(){ lock.lock(); try { while(x!=1){ condition1.await(); } System.out.println(Thread.currentThread().getName()+":aaa"); x=2; condition2.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void b(){ lock.lock(); try { while(x!=2){ condition2.await(); } System.out.println(Thread.currentThread().getName()+":bbb"); x=3; condition3.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public void c(){ lock.lock(); try { while(x!=3){ condition3.await(); } System.out.println(Thread.currentThread().getName()+":ccc"); x=1; condition1.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }
執行結果如下:
對於上面代碼簡單分析:代碼中包含簡單的生產者消費者流程和Lock實現三部曲,即重複判斷條件,執行邏輯,喚醒其他線程和產生鎖,加鎖,解鎖。注意這裡一點,條件判斷一定要重複判斷,不然可能會導致線程假醒影響結果。
因為當線程處於等待狀態時,線程會釋放資源,等到被喚醒的時候,從上次await的地方醒來繼續執行,這時條件判斷成立,執行await,其他線程再修改條件使得本線程被喚醒,此時本線程不會繼續判斷,而是繼續執行,如果使用循環判斷就能檢驗出條件被修改。


[ljg58026 ] Java Lock鎖多線程中實現流水線任務已經有240次圍觀

http://coctec.com/docs/java/show-post-232584.html