日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java sleep join_Java多線程之sleep,wait,join和yield關鍵字

發布時間:2024/10/8 java 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java sleep join_Java多線程之sleep,wait,join和yield關鍵字 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在java或者android中,使用Thread和Runnable就可以玩多線程了,這個成本比較低,也沒什么好說的,今天主要是針對多線程中主要的關鍵字wait,sleep,join和yield做個筆記,加強一下印象。

wait

wait方法一般都是和notity()或者notifyAll()成對出現的。當某個線程執行到wait()方法時,它就進入到一個和該對象相關的等待池中,同時失去了對象的鎖功能,使得其他線程可以訪問該對象。用戶可以使用notify或者notifyAll或者指定睡眠時間來喚醒當前等待池中的線程。wait,notify和notifyAll方法都必須放在synchronized 代碼塊中,否則就會報java.lang.IllegalMonitorStateException。

下面的例子中,在主線程中會存在一個waitObject對象使用wait方法進行等待,而開啟子線程睡眠3秒之后,notifyAll該waitObject對象,使得主線程繼續執行:private static Object waitObject = new Object();

public static void main(String[] args) {

System.out.println("主線程開始運行");

WaitThread thread = new WaitThread();

thread.start();

long t1 = System.currentTimeMillis();

try{

synchronized(waitObject) {

System.out.println("主線程等待");

waitObject.wait();

System.out.println("主線程等待結束");

}

}catch(Exception e){

e.printStackTrace();

}

long t2 = System.currentTimeMillis();

System.out.println("最終時間為:" + (t2 - t1));

}

//定義等待線程

static class WaitThread extends Thread{

@Override

public void run() {

System.out.println("進入子線程run方法");

try{

sleep(3000);

synchronized(waitObject) {

waitObject.notifyAll();

System.out.println("子線程notifyAll結束");

}

}catch(Exception e) {

e.printStackTrace();

}

}

}

程序運行的結果為:

可見wait和notity可用於等待機制的實現,當條件不滿足時進行等待,一旦條件滿足,則notity或者notifyAll喚醒等待線程繼續執行。經典的消費者-生產者模式可以使用wait和notity進行設計。

join

等待目標線程執行完成之后再繼續執行。說的比較含糊,還是來看看例子吧。下面有兩個工作子線程,都需要進行2s的耗時才能完成任務:public static void main(String[] args) throws Exception {

Thread t1 = new WorkThread("work1");

Thread t2 = new WorkThread("work2");

t1.start();

//t1.join();

t2.start();

//t2.join();

System.out.println("當前主線程結束");

}

//工作線程

static class WorkThread extends Thread{

public WorkThread(String name){

super(name);

}

@Override

public void run() {

try {

sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("the current thread is " + getName());

}

}

首先先注釋掉join方法,直接運行,可以看到的結果如下圖:

我們可以看到,主線程首先執行完成,而后兩個子線程分別執行完成,現在我們打開我們的t1.join()和t2.join()方法,得出的結果為:

程序執行的順序是 t1->t2->main thread,相當於三個程序的串聯執行,這也就是join的作用,一旦某個線程使用了join,那么它就先執行完畢,其他線程才有機會繼續執行。

yield

線程禮讓。使用yield方法的線程將由運行狀態轉變為就緒狀態,也就是讓出執行的狀態,讓其他線程得以優先執行,但是其他線程未必一定是有限執行的。簡單通俗一點,就是線程先等著,我會讓其他線程有優先的機會去運行。下面的例子可以簡單說明問題:有兩個單獨的子線程t1,t2分別獨自運行,t1中run遍歷到4時,會執行yield方法,那么我們的猜測就是此時t1將會變回就緒狀態,不再搶奪CPU資源,等到其他線程執行完畢后,再次從就緒狀態變為運行狀態,從而完成以后的任務。代碼如下:public static void main(String[] args) {

//線程t1運行到4時 會執行yield方法

Thread t1 = new YieldClass("線程1",4);

//線程t2將一直運行下去

Thread t2 = new YieldClass("線程2",-1);

t1.start();

t2.start();

System.out.println("主線程結束");

}

static class YieldClass extends Thread{

public int mIndex ;

public YieldClass(String name ,int index) {

super(name);

this.mIndex = index;

}

@Override

public void run() {

for(int i = 0 ; i < 10 ; i++) {

System.out.println(Thread.currentThread().getName() + "---" + i);

if(i == mIndex) {

yield();

}

}

}

}

我們來看運行的效果圖:

可以看到圖中,t1和t2先並行運行,可是當t1運行到4時,由於執行了yield方法,此時t1將會變為就緒狀態,t2線程會執行下去,t2線程執行完成之后,t1才會繼續執行,跟我們預想的方式是一樣的。

sleep

sleep方法是我們平常用得最多的,它是Thread的靜態函數,作用是使得調用的Thread進入休眠狀態。由於是Static修飾的方法,因此不能修改對象的鎖機制,所以當一個synchronized塊中調用了sleep方法,線程雖然休眠了,但是對象的鎖機制並沒有被釋放。其他線程將會無法訪問到這個對象。下面舉個例子:有兩個子線程,一個需要睡眠3s,另一個不需要睡眠,兩個子線程都使用了synchronized塊,我們來看看兩個線程結束之后所用的時間,代碼如下:public class TestSleep {

private static Object mLock = new Object();

public static void main(String[] args) {

Thread t1 = new SleepThread();

Thread t2 = new WordThread() ;

t1.start();

t2.start();

System.out.println("-----主線程執行完成-----"+ System.currentTimeMillis());

}

static class SleepThread extends Thread {

@Override

public void run() {

synchronized(mLock){

try {

sleep(3000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("----睡眠線程執行完成-----" + System.currentTimeMillis());

}

}

}

static class WordThread extends Thread{

@Override

public void run() {

synchronized (mLock) {

System.out.println("----工作線程執行完成-----" + System.currentTimeMillis());

}

}

}

}

結果為:

我們發現了睡眠線程和工作線程幾乎都是等待了3秒之后才結束的,這就表明了sleep引用了對象鎖,其他線程將無法訪問該對象了。我們去掉synchronized代碼塊,再來看一次結果:

我們發現睡眠線程和主線程幾乎同時完成工作,只有睡眠線程睡眠3秒之后才結束工作,由於沒有引用相同的對象,線程之間不影響各自的工作,此時就不存在同步的問題了。

好了,今天基本上就說到這里了,由於以前很少了解這些東西,以致很多關於多線程方面的東西都看得不是很懂,今天算是個入門吧。

總結

以上是生活随笔為你收集整理的java sleep join_Java多線程之sleep,wait,join和yield關鍵字的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。