一、sleep與wait方法的區別
#根本區別:sleep是Thread類別中的方法,不會馬上進入運作狀態,wait是Object類別中的方法,一旦物件呼叫了wait方法,就必須採用notify()和notifyAll()方法喚醒該進程
釋放同步鎖定:sleep會釋放cpu,但是sleep不會釋放同步鎖定的資源,wait會釋放同步鎖定資源
使用範圍:sleep可以在任何地方使用,但wait只能在synchronized的同步方法或是程式碼區塊中使用
異常處理: sleep需要捕獲異常,而wait不需要捕獲異常
二、wait方法
讓目前執行程式碼的執行緒進行等待. (把執行緒放到等待佇列中)
釋放目前的鎖定
#滿足某一條件時被喚醒, 重新嘗試取得這個鎖定.
wait 要搭配synchronized 來使用,脫離synchronized 使用wait 會直接拋出例外.
wait方法的使用
wait方法
/** * wait的使用 */ public class WaitDemo1 { public static void main(String[] args) { Object lock = new Object(); Thread t1 = new Thread(() -> { System.out.println("线程1开始执行"); try { synchronized (lock) { System.out.println("线程1调用wait方法...."); // 无限期的等待状态 lock.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程1执行完成"); }, "线程1"); t1.start(); } }
有參wait線程和無參子wait線程
/** * 有参wait线程和无参wait线程 */ public class WaitDemo2 { public static void main(String[] args) { Object lock1 = new Object(); Object lock2 = new Object(); Thread t1 = new Thread(()->{ System.out.println("线程1开始执行"); synchronized (lock1){ try { lock1.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程1执行完成"); } },"无参wait线程"); t1.start(); Thread t2 = new Thread(()->{ System.out.println("线程2开始执行"); synchronized (lock2){ try { lock2.wait(60*60*1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程2执行完成"); } },"有参wait线程"); t2.start(); } }
wait結束等待的條件
①其他執行緒呼叫該物件的notify 方法.
②wait 等待時間超時(wait 方法提供一個帶有timeout 參數的版本, 來指定等待時間).
③其他執行緒呼叫該等待執行緒的interrupted 方法, 導致wait 拋出InterruptedException 例外
三、notify和notifyAll方法
notify 方法只是喚醒某一個等待的執行緒
方法notify()也要在同步方法或同步區塊中調用,該方法是用來通知那些可能等待該物件的物件鎖的其它線程
如果有多個執行緒等待,隨機挑選一個wait狀態的執行緒
在notify()方法後,目前執行緒不會馬上釋放該物件鎖,要等到執行notify()方法的執行緒將程式執行完,也就是退出同步程式碼區塊之後才會釋放物件鎖定
#notify方法的使用
/** * wait的使用, 如果有多个线程等待,随机挑选一个wait状态的线程 */ public class WaitNotifyDemo { public static void main(String[] args) { Object lock1 = new Object(); Object lock2 = new Object(); Thread t1 = new Thread(()->{ System.out.println("线程1开始执行"); try { synchronized (lock1) { System.out.println("线程1调用wait方法"); lock1.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程1执行完成"); },"线程1"); Thread t2 = new Thread(()->{ System.out.println("线程2开始执行"); try { synchronized (lock1) { System.out.println("线程2调用wait方法"); lock1.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程2执行完成"); },"线程2"); t1.start(); t2.start(); // 唤醒 lock1 对象上休眠的线程的(随机唤醒一个) Thread t3 = new Thread(()->{ try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程3开始执行"); synchronized (lock1){ //发出唤醒通知 System.out.println("执行了唤醒"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } },"线程3"); t3.start(); } }
notifyAll方法可以一次喚醒所有的等待執行緒
notifyAll方法的使用
/** * notifyAll-唤醒所有线程 */ public class WaitNotifyAll { public static void main(String[] args) { Object lock = new Object(); new Thread(() -> { System.out.println("线程1:开始执行"); synchronized (lock) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程1:执行完成"); } }, "无参wait线程").start(); new Thread(() -> { synchronized (lock) { System.out.println("线程2:开始执行 |" + LocalDateTime.now()); try { lock.wait(60 * 60 * 60 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程2:执行完成 | " + LocalDateTime.now()); } }, "有参wait线程").start(); new Thread(() -> { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock) { System.out.println("唤醒所有线程"); lock.notifyAll(); } }).start(); } }
notify和notifyAll方法的差異
當你呼叫notify時,只有一個等待執行緒會被喚醒而且它不能保證哪個執行緒會被喚醒,這取決於執行緒調度器。
呼叫notifyAll方法,那麼等待該鎖定的所有執行緒都會被喚醒,但是在執行剩餘的程式碼之前,所有被喚醒的執行緒都將爭奪鎖定,這就是為什麼在循環上呼叫wait,因為如果多個執行緒被喚醒,那麼執行緒是將獲得鎖定將首先執行,它可能會重置等待條件,這將迫使後續執行緒等待。
因此,notify和notifyAll之間的關鍵區別在於notify()只會喚醒一個線程,而notifyAll方法將喚醒所有執行緒。
以上是Java中sleep和wait方法有什麼差別的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JVM的工作原理是將Java代碼轉換為機器碼並管理資源。 1)類加載:加載.class文件到內存。 2)運行時數據區:管理內存區域。 3)執行引擎:解釋或編譯執行字節碼。 4)本地方法接口:通過JNI與操作系統交互。

JVM使Java實現跨平台運行。 1)JVM加載、驗證和執行字節碼。 2)JVM的工作包括類加載、字節碼驗證、解釋執行和內存管理。 3)JVM支持高級功能如動態類加載和反射。

Java應用可通過以下步驟在不同操作系統上運行:1)使用File或Paths類處理文件路徑;2)通過System.getenv()設置和獲取環境變量;3)利用Maven或Gradle管理依賴並測試。 Java的跨平台能力依賴於JVM的抽象層,但仍需手動處理某些操作系統特定的功能。

Java在不同平台上需要進行特定配置和調優。 1)調整JVM參數,如-Xms和-Xmx設置堆大小。 2)選擇合適的垃圾回收策略,如ParallelGC或G1GC。 3)配置Native庫以適應不同平台,這些措施能讓Java應用在各種環境中發揮最佳性能。

Osgi,Apachecommonslang,JNA和JvMoptionsareeForhandlingForhandlingPlatform-specificchallengesinjava.1)osgimanagesdeppedendendencenciesandisolatescomponents.2)apachecommonslangprovidesitorityfunctions.3)

JVMmanagesgarbagecollectionacrossplatformseffectivelybyusingagenerationalapproachandadaptingtoOSandhardwaredifferences.ItemploysvariouscollectorslikeSerial,Parallel,CMS,andG1,eachsuitedfordifferentscenarios.Performancecanbetunedwithflagslike-XX:NewRa

Java代碼可以在不同操作系統上無需修改即可運行,這是因為Java的“一次編寫,到處運行”哲學,由Java虛擬機(JVM)實現。 JVM作為編譯後的Java字節碼與操作系統之間的中介,將字節碼翻譯成特定機器指令,確保程序在任何安裝了JVM的平台上都能獨立運行。

Java程序的編譯和執行通過字節碼和JVM實現平台獨立性。 1)編寫Java源碼並編譯成字節碼。 2)使用JVM在任何平台上執行字節碼,確保代碼的跨平台運行。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript開發工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具