摘要:提供了多線程升級方案將同步替換成了顯示的操作。線程間通信接口可以替代傳統(tǒng)的線程間通信,用替換,用替換,用替換。商品執(zhí)行上述代碼,觀察結(jié)果可以看到,多個(gè)線程同時(shí)生產(chǎn)消費(fèi),由于指定喚醒互異線程,因此并不會引起錯(cuò)誤。
JDK 1.5提供了多線程升級方案
將同步synchronized替換成了顯示的Lock操作。可以實(shí)現(xiàn)喚醒、凍結(jié)指定的線程。
Lock接口
Lock 實(shí)現(xiàn)提供了比使用 synchronized 方法和語句可獲得的更廣泛的鎖定操作。此實(shí)現(xiàn)允許更靈活的結(jié)構(gòu),可以具有差別很大的屬性,可以支持多個(gè)相關(guān)的 Condition 對象。
線程間通信Condition接口
Condition可以替代傳統(tǒng)的線程間通信,用await()替換wait(),用signal()替換notify(),用signalAll()替換notifyAll()。該對象可以通過Lock鎖進(jìn)行獲取。
傳統(tǒng)線程的通信方式,Condition都可以實(shí)現(xiàn)。
注意,Condition是被綁定到Lock上的,要創(chuàng)建一個(gè)Lock的Condition必須用newCondition()方法。
ReentrantLock類
Java.util.concurrent.lock 中的Lock 框架是鎖定的一個(gè)抽象,它允許把鎖定的實(shí)現(xiàn)作為 Java 類,而不是作為語言的特性來實(shí)現(xiàn)。這就為Lock 的多種實(shí)現(xiàn)留下了空間,各種實(shí)現(xiàn)可能有不同的調(diào)度算法、性能特性或者鎖定語義。
ReentrantLock 類實(shí)現(xiàn)了Lock ,它擁有與synchronized 相同的并發(fā)性和內(nèi)存語義,但是添加了類似鎖投票、定時(shí)鎖等候和可中斷鎖等候的一些特性。此外,它還提供了在激烈爭用情況下更佳的性能。(換句話說,當(dāng)許多線程都想訪問共享資源時(shí),JVM 可以花更少的時(shí)候來調(diào)度線程,把更多時(shí)間用在執(zhí)行線程上。)
用法示例:
private Lock lock = new ReentrantLock();//定義多態(tài)ReentrantLock類對象 private Condition cond_pro = lock.newCondition();//Condition是被綁定到Lock上的,要創(chuàng)建一個(gè)Lock的Condition必須用Lock對象的newCondition()方法。 private Condition cond_con = lock.newCondition();//一個(gè)lock可以有多個(gè)相關(guān)的condition
首先創(chuàng)建一個(gè)ReentrantLock類的多態(tài)對象,即建立一把鎖。然后將這把鎖與兩個(gè)Condition對象關(guān)聯(lián)。
實(shí)例:
import java.util.concurrent.locks.*; class ProducerConsumerDemo { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r);//生產(chǎn)者對象 Consumer con = new Consumer(r);//消費(fèi)者對象 Thread t1 = new Thread(pro); Thread t2 = new Thread(pro); Thread t3 = new Thread(con); Thread t4 = new Thread(con); t1.start(); t2.start(); t3.start(); t4.start(); } } class Resource { private String name; private int count = 1; private boolean flag = false; private Lock lock = new ReentrantLock();//定義一個(gè)實(shí)現(xiàn)Lock接口的ReentrantLock類對象 private Condition cond_pro = lock.newCondition();//Condition是被綁定到Lock上的,要創(chuàng)建一個(gè)Lock的Condition必須用Lock對象的newCondition()方法。 private Condition cond_con = lock.newCondition();//一個(gè)lock可以有多個(gè)相關(guān)的condition public void set(String name) throws InterruptedException//生產(chǎn)方法 //注意這里拋出await()方法異常聲明,交給調(diào)用者處理 { lock.lock(); //手動加同步鎖 try { while (flag) //if→while 此時(shí)若生產(chǎn)完一個(gè)以后喚醒了另一個(gè)生產(chǎn)者,則再次判斷,避免了兩個(gè)生產(chǎn)者同時(shí)生產(chǎn) cond_pro.await(); //凍結(jié)生產(chǎn)方法 this.name = name+"____"+count++; System.out.println(Thread.currentThread().getName()+"_______"+"生產(chǎn)者"+this.name); flag = true; cond_con.signal(); //喚醒消費(fèi)方法,利用了condition的signal()指定喚醒對象 } finally // { lock.unlock(); } } public void out()throws InterruptedException { lock.lock(); try { while (!flag) cond_con.await(); System.out.println(Thread.currentThread().getName()+"______"+"消費(fèi)者"+this.name); flag = false; cond_pro.signal(); } finally //釋放鎖必須得到執(zhí)行 { lock.unlock(); } } } class Consumer implements Runnable { private Resource res; public Consumer(Resource res) { this.res = res; } public void run() { while (true) { try //由于out()方法拋出了異常聲明,這里必須捕獲。 { res.out(); } catch (InterruptedException e) { } } } } class Producer implements Runnable { private Resource res; public Producer(Resource res) { this.res = res; } public void run() { while (true) { try { res.set("+商品+"); } catch (InterruptedException e) { } } } }
執(zhí)行上述代碼,觀察結(jié)果:
可以看到,多個(gè)線程同時(shí)生產(chǎn)、消費(fèi),由于指定喚醒互異線程,因此并不會引起錯(cuò)誤。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/69842.html
摘要:線程可以被稱為輕量級進(jìn)程。一個(gè)守護(hù)線程是在后臺執(zhí)行并且不會阻止終止的線程。其他的線程狀態(tài)還有,和。上下文切換是多任務(wù)操作系統(tǒng)和多線程環(huán)境的基本特征。在的線程中并沒有可供任何對象使用的鎖和同步器。 原文:Java Multi-Threading and Concurrency Interview Questions with Answers 翻譯:并發(fā)編程網(wǎng) - 鄭旭東 校對:方騰飛 多...
摘要:多線程和并發(fā)問題是技術(shù)面試中面試官比較喜歡問的問題之一。線程可以被稱為輕量級進(jìn)程。一個(gè)守護(hù)線程是在后臺執(zhí)行并且不會阻止終止的線程。其他的線程狀態(tài)還有,和。上下文切換是多任務(wù)操作系統(tǒng)和多線程環(huán)境的基本特征。 多線程和并發(fā)問題是 Java 技術(shù)面試中面試官比較喜歡問的問題之一。在這里,從面試的角度列出了大部分重要的問題,但是你仍然應(yīng)該牢固的掌握J(rèn)ava多線程基礎(chǔ)知識來對應(yīng)日后碰到的問題。(...
摘要:本文對多線程基礎(chǔ)知識進(jìn)行梳理,主要包括多線程的基本使用,對象及變量的并發(fā)訪問,線程間通信,的使用,定時(shí)器,單例模式,以及線程狀態(tài)與線程組。源碼采用構(gòu)建,多線程這部分源碼位于模塊中。通知可能等待該對象的對象鎖的其他線程。 本文對多線程基礎(chǔ)知識進(jìn)行梳理,主要包括多線程的基本使用,對象及變量的并發(fā)訪問,線程間通信,lock的使用,定時(shí)器,單例模式,以及線程狀態(tài)與線程組。 寫在前面 花了一周時(shí)...
摘要:程序執(zhí)行時(shí),至少會有一個(gè)線程在運(yùn)行,這個(gè)運(yùn)行的線程被稱為主線程。程序的終止是指除守護(hù)線程以外的線程全部終止。多線程程序由多個(gè)線程組成的程序稱為多線程程序。線程休眠期間可以被中斷,中斷將會拋出異常。 線程 我們在閱讀程序時(shí),表面看來是在跟蹤程序的處理流程,實(shí)際上跟蹤的是線程的執(zhí)行。 單線程程序 在單線程程序中,在某個(gè)時(shí)間點(diǎn)執(zhí)行的處理只有一個(gè)。 Java 程序執(zhí)行時(shí),至少會有一個(gè)線程在運(yùn)行...
摘要:前文回顧上一篇文章重點(diǎn)嘮叨了中協(xié)調(diào)線程間通信的機(jī)制,它有力的保證了線程間通信的安全性以及便利性。所以同一時(shí)刻廚師線程和服務(wù)員線程不會同時(shí)在等待隊(duì)列中。對于在操作系統(tǒng)中線程的阻塞狀態(tài),語言中用和這三個(gè)狀態(tài)分別表示。 前文回顧 上一篇文章重點(diǎn)嘮叨了java中協(xié)調(diào)線程間通信的wait/notify機(jī)制,它有力的保證了線程間通信的安全性以及便利性。本篇將介紹wait/notify機(jī)制的一個(gè)應(yīng)用...
閱讀 2559·2021-11-15 18:14
閱讀 1768·2021-10-14 09:42
閱讀 3830·2021-10-11 10:58
閱讀 4012·2021-10-09 09:44
閱讀 2531·2021-09-26 09:55
閱讀 2528·2021-09-24 10:38
閱讀 2089·2021-09-04 16:48
閱讀 3321·2021-09-02 15:21