如何在Java項(xiàng)目中實(shí)現(xiàn)多線程的阻塞與喚醒?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
創(chuàng)新互聯(lián)專注于維西網(wǎng)站建設(shè)服務(wù)及定制,我們擁有豐富的企業(yè)做網(wǎng)站經(jīng)驗(yàn)。 熱誠為您提供維西營銷型網(wǎng)站建設(shè),維西網(wǎng)站制作、維西網(wǎng)頁設(shè)計(jì)、維西網(wǎng)站官網(wǎng)定制、小程序定制開發(fā)服務(wù),打造維西網(wǎng)絡(luò)公司原創(chuàng)品牌,更為您提供維西網(wǎng)站排名全網(wǎng)營銷落地服務(wù)。
java線程的阻塞及喚醒
1. sleep() 方法:
sleep(…毫秒),指定以毫秒為單位的時(shí)間,使線程在該時(shí)間內(nèi)進(jìn)入線程阻塞狀態(tài),期間得不到cpu的時(shí)間片,等到時(shí)間過去了,線程重新進(jìn)入可執(zhí)行狀態(tài)。(暫停線程,不會(huì)釋放鎖)
//測(cè)試sleep()方法 class Thread7 implements Runnable{ @Override public void run() { for(int i=0;i<50;i++){ System.out.println(Thread.currentThread().getName()+"num="+i); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Thread8 implements Runnable{ @Override public void run() { for(int i=0;i<1000;i++){ System.out.println(Thread.currentThread().getName()+"num="+i); } } } public static void main(String[] args) { /* * 測(cè)試線程阻塞 */ //測(cè)試sleep()方法 Thread7 t7=new Thread7(); Thread8 t8=new Thread8(); Thread t81=new Thread(t8, "餃子"); Thread t71=new Thread(t7, "包子"); Thread t72=new Thread(t7, "面包"); t71.start(); t81.start(); t72.start(); }
2.suspend() 和 resume() 方法:。
掛起和喚醒線程,suspend()使線程進(jìn)入阻塞狀態(tài),只有對(duì)應(yīng)的resume()被調(diào)用的時(shí)候,線程才會(huì)進(jìn)入可執(zhí)行狀態(tài)。(不建議用,容易發(fā)生死鎖)
//測(cè)試suspend()和resume()方法 class Thread9 implements Runnable{ @Override public void run() { for(long i=0;i<500000000;i++){ System.out.println(Thread.currentThread().getName()+" num= "+i); } } } public static void main(String[] args) { //測(cè)試suspend和resume Thread9 t9=new Thread9(); Thread t91=new Thread(t9,"包子"); t91.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t91.suspend(); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } t91.resume(); }
(在控制臺(tái)打印輸出的時(shí)候,會(huì)停頓2秒鐘,然后再繼續(xù)打印。)
3. yield() 方法:
會(huì)使的線程放棄當(dāng)前分得的cpu時(shí)間片,但此時(shí)線程任然處于可執(zhí)行狀態(tài),隨時(shí)可以再次分得cpu時(shí)間片。yield()方法只能使同優(yōu)先級(jí)的線程有執(zhí)行的機(jī)會(huì)。調(diào)用 yield() 的效果等價(jià)于調(diào)度程序認(rèn)為該線程已執(zhí)行了足夠的時(shí)間從而轉(zhuǎn)到另一個(gè)線程。(暫停當(dāng)前正在執(zhí)行的線程,并執(zhí)行其他線程,且讓出的時(shí)間不可知)
//測(cè)試yield()方法 class Thread10 implements Runnable{ @Override public void run() { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+" num= "+i); if(i==33){ Thread.yield(); } } } } public static void main(String[] args) { //測(cè)試yield Thread10 t10 =new Thread10(); Thread t101=new Thread(t10, "包子"); Thread t102=new Thread(t10, "面包"); t101.start(); t102.start(); } /* 運(yùn)行結(jié)果為: …… 包子 num= 24 包子 num= 25 包子 num= 26 包子 num= 27 包子 num= 28 包子 num= 29 包子 num= 30 包子 num= 31 包子 num= 32 包子 num= 33 面包 num= 0 面包 num= 1 面包 num= 2 面包 num= 3 …… 面包 num= 30 面包 num= 31 面包 num= 32 面包 num= 33 包子 num= 34 包子 num= 35 包子 num= 36 包子 num= 37 包子 num= 38 …… */
(可以看到,當(dāng)數(shù)字為33時(shí),都發(fā)生了交替。)
4.wait() 和 notify() 方法:
兩個(gè)方法搭配使用,wait()使線程進(jìn)入阻塞狀態(tài),調(diào)用notify()時(shí),線程進(jìn)入可執(zhí)行狀態(tài)。wait()內(nèi)可加或不加參數(shù),加參數(shù)時(shí)是以毫秒為單位,當(dāng)?shù)搅酥付〞r(shí)間或調(diào)用notify()方法時(shí),進(jìn)入可執(zhí)行狀態(tài)。(屬于Object類,而不屬于Thread類,wait( )會(huì)先釋放鎖住的對(duì)象,然后再執(zhí)行等待的動(dòng)作。由于wait( )所等待的對(duì)象必須先鎖住,因此,它只能用在同步化程序段或者同步化方法內(nèi),否則,會(huì)拋出異常IllegalMonitorStateException.)
//測(cè)試wait()和notify()方法 //用生產(chǎn)者和消費(fèi)者模式模擬這一過程 /*消費(fèi)者 */ class Consumer implements Runnable { private Vector obj; public Consumer(Vector v) { this.obj = v; } public void run() { synchronized (obj) { while (true) { try { if (obj.size() == 0) { obj.wait(); } System.out.println("消費(fèi)者:我要買面包。"); System.out.println("面包數(shù): " + obj.size()); obj.clear(); obj.notify(); } catch (Exception e) { e.printStackTrace(); } } } } } /* 生產(chǎn)者 */ class Producter implements Runnable { private Vector obj; public Producter(Vector v) { this.obj = v; } public void run() { synchronized (obj) { while (true) { try { if (obj.size() != 0) { obj.wait(); } obj.add(new String("面包")); obj.notify(); System.out.println("生產(chǎn)者:面包做好了。"); Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } } } } } public static void main(String[] args) { //測(cè)試wait()和notify() Vector obj = new Vector(); Thread consumer = new Thread(new Consumer(obj)); Thread producter = new Thread(new Producter(obj)); consumer.start(); producter.start(); }
5.join()方法
也叫線程加入。是當(dāng)前線程A調(diào)用另一個(gè)線程B的join()方法,當(dāng)前線程轉(zhuǎn)A入阻塞狀態(tài),直到線程B運(yùn)行結(jié)束,線程A才由阻塞狀態(tài)轉(zhuǎn)為可執(zhí)行狀態(tài)。
//測(cè)試join class Thread11 implements Runnable{ @Override public void run() { System.out.println("Start Progress."); try { for(int i=0;i<5;i++){ System.out.println("Thread11線程 : "+i); Thread.sleep(1000); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("End Progress."); } } public static void main(String[] args) { //測(cè)試join Thread11 t11=new Thread11(); Thread t111=new Thread(t11); t111.start(); try { t111.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("hi,I'm Main線程"); } /* 運(yùn)行結(jié)果為: Start Progress. Thread11線程 : 0 Thread11線程 : 1 Thread11線程 : 2 Thread11線程 : 3 Thread11線程 : 4 End Progress. hi,I'm Main線程 */
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對(duì)創(chuàng)新互聯(lián)的支持。
當(dāng)前題目:如何在Java項(xiàng)目中實(shí)現(xiàn)多線程的阻塞與喚醒
文章起源:http://www.rwnh.cn/article4/jdcpoe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、網(wǎng)站導(dǎo)航、響應(yīng)式網(wǎng)站、網(wǎng)站維護(hù)、手機(jī)網(wǎng)站建設(shè)、軟件開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)