1. 程式人生 > >Java執行緒中yield與join方法的區別

Java執行緒中yield與join方法的區別

長期以來,多執行緒問題頗為受到面試官的青睞。雖然我個人認為我們當中很少有人能真正獲得機會開發複雜的多執行緒應用(在過去的七年中,我得到了一個機會),但是理解多執行緒對增加你的信心很有用。之前,我討論了一個wait()和sleep()方法區別的問題,這一次,我將會討論join()和yield()方法的區別。坦白的說,實際上我並沒有用過其中任何一個方法,所以,如果你感覺有不恰當的地方,請提出討論。

Java執行緒排程的一點背景

在各種各樣的執行緒中,Java虛擬機器必須實現一個有優先權的、基於優先順序的排程程式。這意味著Java程式中的每一個執行緒被分配到一定的優先權,使用定義好的範圍內的一個正整數表示。優先順序可以被開發者改變。即使執行緒已經運行了一定時間,Java虛擬機器也不會改變其優先順序

優先順序的值很重要,因為Java虛擬機器和下層的作業系統之間的約定是作業系統必須選擇有最高優先權的Java執行緒執行。所以我們說Java實現了一個基於優先權的排程程式。該排程程式使用一種有優先權的方式實現,這意味著當一個有更高優先權的執行緒到來時,無論低優先順序的執行緒是否在執行,都會中斷(搶佔)它。這個約定對於作業系統來說並不總是這樣,這意味著作業系統有時可能會選擇執行一個更低優先順序的執行緒。(我憎恨多執行緒的這一點,因為這不能保證任何事情)

注意Java並不限定執行緒是以時間片執行,但是大多數作業系統卻有這樣的要求。在術語中經常引起混淆:搶佔經常與時間片混淆。事實上,搶佔意味著只有擁有高優先順序的執行緒可以優先於低優先順序的執行緒執行,但是當執行緒擁有相同優先順序的時候,他們不能相互搶佔。它們通常受時間片管制,但這並不是Java的要求。

理解執行緒的優先權

接下來,理解執行緒優先順序是多執行緒學習很重要的一步,尤其是瞭解yield()函式的工作過程。

  1. 記住當執行緒的優先順序沒有指定時,所有執行緒都攜帶普通優先順序。
  2. 優先順序可以用從1到10的範圍指定。10表示最高優先順序,1表示最低優先順序,5是普通優先順序。
  3. 記住優先順序最高的執行緒在執行時被給予優先。但是不能保證執行緒在啟動時就進入執行狀態。
  4. 與線上程池中等待執行機會的執行緒相比,當前正在執行的執行緒可能總是擁有更高的優先順序。
  5. 由排程程式決定哪一個執行緒被執行。
  6. t.setPriority()用來設定執行緒的優先順序。
  7. 記住線上程開始方法被呼叫之前,執行緒的優先順序應該被設定。
  8. 你可以使用常量,如MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY來設定優先順序

現在,當我們對執行緒排程和執行緒優先順序有一定理解後,讓我們進入主題。

yield()方法

理論上,yield意味著放手,放棄,投降。一個呼叫yield()方法的執行緒告訴虛擬機器它樂意讓其他執行緒佔用自己的位置。這表明該執行緒沒有在做一些緊急的事情。注意,這僅是一個暗示,並不能保證不會產生任何影響。

在Thread.java中yield()定義如下:

1 2 3 4 5 6 7 /** * A hint to the scheduler that the current thread is willing to yield its current use of a processor. The scheduler is free to ignore * this hint. Yield is a heuristic attempt to improve relative progression between threads that would otherwise over-utilize a CPU. * Its use should be combined with detailed profiling and benchmarking to ensure that it actually has the desired effect. */ public static native void yield();

讓我們列舉一下關於以上定義重要的幾點:

  • Yield是一個靜態的原生(native)方法
  • Yield告訴當前正在執行的執行緒把執行機會交給執行緒池中擁有相同優先順序的執行緒。
  • Yield不能保證使得當前正在執行的執行緒迅速轉換到可執行的狀態
  • 它僅能使一個執行緒從執行狀態轉到可執行狀態,而不是等待或阻塞狀態

yield()方法使用示例

在下面的示例程式中,我隨意的建立了名為生產者和消費者的兩個執行緒。生產者設定為最小優先順序,消費者設定為最高優先順序。在Thread.yield()註釋和非註釋的情況下我將分別執行該程式。沒有呼叫yield()方法時,雖然輸出有時改變,但是通常消費者行先打印出來,然後事生產者。

呼叫yield()方法時,兩個執行緒依次列印,然後將執行機會交給對方,一直這樣進行下去。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 package test.core.threads; public class YieldExample { public static void main(String[] args) { Thread producer = new

相關推薦

Java執行yieldjoin方法區別

長期以來,多執行緒問題頗為受到面試官的青睞。雖然我個人認為我們當中很少有人能真正獲得機會開發複雜的多執行緒應用(在過去的七年中,我得到了一個機會),但是理解多執行緒對增加你的信心很有用。之前,我討論了一個wait()和sleep()方法區別的問題,這一次,我將會討

java執行yield()和join()的區別

package test.core.threads; public class JoinExample { public static void main(String[] args) throws InterruptedException { Thread t = new Thr

執行yield()和join()方法的對比

1.yield():呼叫此方法的執行緒,釋放當前cpu的執行權class SubTread extends Thread{ @Override public void run() { for(int i=1;i<=100;i++){ System.out.

Java執行休眠方法sleep、執行讓步yieldjoin方法

執行緒休眠(sleep方法) 執行緒休眠:讓執行緒暫緩執行,等到預計時間之後再恢復執行。 執行緒休眠會交出cpu,讓cpu去執行其他任務,但是不會釋放鎖。 比如:當前執行緒sleep休眠了,但是如果此執行緒在休眠前持有某個物件的鎖,那就算它休眠了其他執行緒也不能獲取到這個物件的鎖。

java執行yield(),sleep(),wait()區別詳解

1、sleep() 使當前執行緒(即呼叫該方法的執行緒)暫停執行一段時間,讓其他執行緒有機會繼續執行,但它並不釋放物件鎖。也就是說如果有synchronized同步快,其他執行緒仍然不能訪問共享資料。

java挑戰高併發(7):java 執行yield的用法

Thread.yield()方法作用是:暫停當前正在執行的執行緒物件,並執行其他執行緒。 yield()應該做的是讓當前執行執行緒回到可執行狀態,以允許具有相同優先順序的其他執行緒獲得執行機會。因此,使用yield()的目的是讓相同優先順序的執行緒之間能適當的輪轉執行。但

執行sleep()wait()的區別

對時間的指定。  1,sleep方法必須指定時間。  2,wait方法有過載形式,可以指定時間,也可以不指定時間。 對於執行權和鎖的操作.:  1,sleep():釋放執行權,不釋放鎖,因為肯定能醒,肯定可以恢復到臨時阻塞狀態。  2,wait():釋

執行FutureFutureTask的區別和聯絡

4.2 使用Callable+FutureTask獲取執行結果 package com.zejian.Executor; import java.util.concurrent.ExecutorService; import java.util.concurrent.Execut

一心多用多執行-細談java執行池submitexecute的區別

深夜學習,發現ThreadPoolExecutor裡面一個小知識點,故開熱點連wifi怒寫submit與execute方法的區別。 1.問題的來源 在看書的時候,涉及到java執行緒池問題的時候常常面臨這樣一個問題。當定義了一個Runnable物件想提交

Python——程序執行以及yieldreturn的區別

一、程序與執行緒        1. 一個程式至少有一個程序,一個程序至少有一個執行緒        2. 執行緒的劃分尺度小於程序,使得多執行緒程式的併發性高        3. 程序在執行過程中擁有獨立的記憶體單元,而多個執行緒共享記憶體,從而極大地提高了程式的執行

Java執行sleep()、wait()和notify()和notifyAll()、yield()、join()等方法的用法和區別

Java執行緒中sleep()、wait()和notify()和notifyAll()、suspend和resume()、yield()、join()、interrupt()的用法和區別從作業系統的角度講,os會維護一個ready queue(就緒的執行緒佇列)。並且在某一

執行的一些常用方法的用法 join()、yield()、sleep()、wait()、notify()、notifyAll()

1.執行緒休眠sleep();:執行緒有優先順序,但是我們可以用此方法人為的改變它們的優先順序,讓執行緒暫停,它其他執行緒獲得分配空間。 用法:Thread.sleep(2000);//休眠兩秒 2.執行緒讓步yield();就是讓出自己的分配空間給其他執行

Java執行joinyield

public class TestJoin { public static void main(String[] args) { MyThread2 t1 = new MyThread2(

Java 內部類,多執行Synchronizedwait,notify的使用

工作內容: 1.成員內部類    與成員方法,屬性的訪問許可權一致 2.靜態內部類    修飾符 stactic 類名{...} 3.匿名內部類    new 類名()/介面名(重寫介面方法) 4.區域性內部類    程式碼塊中 5.執行緒Thread wait,noti

Androidjava執行的暫停恢復

在Android中有時我們會遇到類似這樣的問題,我要繪製一個曲線圖,但是我想讓它可以被暫停和繼續。首先,繪圖肯定得用到多執行緒的知識。java的Thread類中自帶suspend和resume兩個方法來實現執行緒的暫停和恢復,可惜的是,現在已經不被建議使用了,而

執行yield()方法的使用

package com.thread; public class TestYield { public static void main(String[] args) { YieldThread yt = new YieldThread(); Thread t1 = new Thr

java執行——執行的常用操作方法

線上程中所有的方法都是在Thread類中。 執行緒操作的主要方法如下: public Thread(Runnable   target )Thread物件接受一個實現了Runnable介面的物件,並例項化這個Thread執行緒! public Thread(Runnable

java執行的interrupt,isInterrupt,interrupted方法以及如何終止執行(一)

在java的執行緒Thread類中有三個方法,比較容易混淆,在這裡解釋一下(1)interrupt:置執行緒的中斷狀態(2)isInterrupt:執行緒是否中斷(3)interrupted:返回執行緒的上次的中斷狀態,並清除中斷狀態舉個例子: 用法:   class 

java執行的interrupt,isInterrupt,interrupted方法

在java的執行緒Thread類中有三個方法,比較容易混淆,在這裡解釋一下 (1)interrupt:置執行緒的中斷狀態 (2)isInterrupt:執行緒是否中斷 (3)interrupted:返回執行緒的上次的中斷狀態,並清除中斷狀態 舉個例子: 用法:  clas

關於多執行sleep、joinyield區別

好了、說了多執行緒,那就不得不說說多執行緒的sleep()、join()和yield()三個方法的區別啦    1、sleep()方法 /** * Causes the currently executing thread to sleep (temporarily cease