wait放弃对象锁_Java线程中wait、await、sleep、yield、join用法总结
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                wait放弃对象锁_Java线程中wait、await、sleep、yield、join用法总结
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.                        
                                一、wait()、notify()、notifyAll()用法
- obj.wait()/obj.wait(long timeout)是Object中的方法,當線程調(diào)用wait()方法,當前線程釋放對象鎖,進入等待隊列。
- obj.notify()/obj.nogifyAll()是Object中的方法,喚醒在此對象上wait()的單個或者所有線程。
測試代碼:
public class ThreadWaitNotify {public static void main(String[] args) throws InterruptedException {//創(chuàng)建一個線程池ExecutorService executorService = Executors.newCachedThreadPool();//創(chuàng)建DemoTest對象DemoTest demoTest = new DemoTest();//用線程池創(chuàng)建線程異步執(zhí)行waitTest方法executorService.submit(() -> demoTest.waitTest());//用線程池創(chuàng)建線程異步執(zhí)行notifyTest方法executorService.submit(() -> demoTest.notifyTest());}//測試wait和notify測試demostatic class DemoTest {//喚醒線程public synchronized void notifyTest() {System.out.println("方法notifyTest開始執(zhí)行了");notify();System.out.println("方法notifyTest執(zhí)行結束了");}//執(zhí)行wait操作將線程掛起,注意必須結合synchronized使用public synchronized void waitTest() {System.out.println("方法waitTest開始執(zhí)行了");try {wait();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("方法waitTest執(zhí)行結束了");}} }打印日志:
方法waitTest開始執(zhí)行了 方法notifyTest開始執(zhí)行了 方法notifyTest執(zhí)行結束了 方法waitTest執(zhí)行結束了從日志中我們可以看出waitTest方法阻塞直到被notifyTest喚醒
二、await()、signal()、signalAll()用法
java.util.concurrent類庫中提供的Condition類來實現(xiàn)線程之間的協(xié)調(diào)。
- condition.await()/condition.await(long time, TimeUnit unit):通過condition調(diào)用,當前線程釋放對象鎖。
- condition.signal()/condition.signalAll():通過signal或者signalAll方法喚醒await掛起的線程。
測試代碼:
public class ThreadAwaitSignal {public static void main(String[] args) {//創(chuàng)建一個線程池ExecutorService executorService = Executors.newCachedThreadPool();//創(chuàng)建DemoTest對象DemoTest demoTest = new DemoTest();//用線程池創(chuàng)建線程異步執(zhí)行awaitTest方法executorService.submit(() -> demoTest.awaitTest());//用線程池創(chuàng)建線程異步執(zhí)行signalTest方法executorService.submit(() -> demoTest.signalTest());}/*** 使用java.util.conncurrent類中提供了Condition類來實現(xiàn)線程之間的協(xié)調(diào)* 可以在Condition上調(diào)用await()方法使線程掛起* 其他線程調(diào)用signal()或者signalAll()來喚醒線程*/static class DemoTest {//定義一個Lock對象用來獲取Condition對象private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();//喚醒線程public void signalTest() {lock.lock();try {System.out.println("方法signalTest開始執(zhí)行了");condition.signalAll();System.out.println("方法signalTest執(zhí)行結束了");} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}//結合lock鎖實現(xiàn)Condition的awaitpublic void awaitTest() {lock.lock();try {System.out.println("方法awaitTest開始執(zhí)行了");condition.await();System.out.println("方法awaitTest執(zhí)行結束了");} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}} }打印日志:
方法awaitTest開始執(zhí)行了 方法signalTest開始執(zhí)行了 方法signalTest執(zhí)行結束了 方法awaitTest執(zhí)行結束了從日志中國可以看出我們得到了和wait同樣的效果。
三 、yield()、join()用法
- Thread.yield():一定是當前線程調(diào)用此方法,當前線程放棄獲取CPU的時間片,由運行態(tài)轉變?yōu)榫途w態(tài),讓操作系統(tǒng)中再次選擇線程執(zhí)行。作用:讓相同優(yōu)先級的線程輪流執(zhí)行,但并不能保證輪流執(zhí)行,根據(jù)解釋我們了解到,轉成就緒態(tài)的的線程還有可能再次選中執(zhí)行。Thread.yield()方法不會導致阻塞。
- t.join()/t.join(long millis):當前線程調(diào)用t2.join()方法,當前線程阻塞但是不會釋放對象鎖,直到t2線程執(zhí)行完畢或者millis時間到,則當前的線程恢復就緒狀態(tài)。作用:讓優(yōu)先級比較高的線程優(yōu)先執(zhí)行。
yield測試代碼:
//yield放棄CPU時間片public static void yieldTest(){//定義一個線程Thread thread = new Thread(() -> {System.out.println(Thread.currentThread().getName() + ": 測試線程開始執(zhí)行。。。");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ": 測試線程執(zhí)行結束了。");});thread.start();System.out.println(Thread.currentThread().getName() + ": 執(zhí)行yield方法");Thread.yield();System.out.println(Thread.currentThread().getName() + ": 主線程開始執(zhí)行");}打印結果:
main: 執(zhí)行yield方法 main: 主線程開始執(zhí)行 Thread-0: 測試線程開始執(zhí)行。。。 Thread-0: 測試線程執(zhí)行結束了。可以看出雖然主線程調(diào)用了yield,但是仍然又開始執(zhí)行了,因此但并不能保證輪流執(zhí)行。
join測試代碼:
//join搶占CPU時間片public static void joinTest() throws InterruptedException {//定義一個線程Thread thread = new Thread(() -> {System.out.println(Thread.currentThread().getName() + ": 測試線程開始執(zhí)行。。。");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + ": 測試線程執(zhí)行結束了。");});thread.start();System.out.println(thread.getName() + ": 執(zhí)行join方法");thread.join();System.out.println(Thread.currentThread().getName() + ": 主線程開始執(zhí)行");}打印日志:
Thread-0: 執(zhí)行join方法 Thread-0: 測試線程開始執(zhí)行。。。 Thread-0: 測試線程執(zhí)行結束了。 main: 主線程開始執(zhí)行從日志中我們可以看出主線程在線程執(zhí)行完成后才開始執(zhí)行。
四、wait()、await()、sleep()、yield、join對比
通過表格對比(join的情況下,t1指代當前線程,t2代表其他線程)
總結
以上是生活随笔為你收集整理的wait放弃对象锁_Java线程中wait、await、sleep、yield、join用法总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 双时隙的工作原理_OFDM调制技术原理是
- 下一篇: python利用特征进行可视化样本显示_
