1. 程式人生 > >執行緒的排程(執行緒休眠,執行緒讓步,執行緒插隊)

執行緒的排程(執行緒休眠,執行緒讓步,執行緒插隊)

程式中的多個執行緒是併發執行的,某個執行緒若想被執行必須要得到CPU的使用權,Java虛擬機器會按照特定的機制為程式中的每個執行緒分配CPU的使用權,這種機制被稱作執行緒的排程。

兩種執行緒排程模式:

分時排程模式:讓所有的執行緒輪流獲得CPU的使用權,並且平均分配每個執行緒佔用的CPU的時間片。

搶佔式排程模式:讓可執行池中優先順序高的執行緒優先佔用CPU,而對於優先順序相同的執行緒,隨機選擇一個執行緒使其佔用CPU,當它失去了CPU的使用權後,再隨機選擇其他執行緒使其佔用CPU。

Java虛擬機器預設採用搶佔式排程模型。

一、執行緒的優先順序

執行緒的優先順序用1~10之間的整數來表示,數字越大優先順序越高。Thread類提供三個靜態常量表示執行緒的優先順序:

MAX_PRIORITY :相當於10

MIN_PRIORITY:相當於1

NORM_PRIORITY:相當於5

通常用setPriority(int 優先順序)對執行緒進行設定,但優先順序調整的是機率,而不是將優先順序低的程序掛起。setPriority 告訴JVM這個執行緒的優先順序,但JVM是否按你請求 (請求,不是要求)辦不確定,就是結果不確定難過(最主要原因是這些優先順序需要作業系統的支援,不同的作業系統對優先順序的支援是不一樣的)

二、執行緒休眠

運用sleep()函式,使正在執行的執行緒暫停一段時間,將CPU讓給別的執行緒,即讓執行緒進入休眠等待狀態。

注意:①sleep()釋放資源不釋放鎖

   ②

sleep(long millis)方法生命丟擲InterruptedException異常,因此在呼叫該方法時應該捕獲異常,或宣告丟擲該異常。

//定義SleepThread類實現Runnable介面
class SleepThread implements Runnable {
	public void run() {
		for (int i = 1; i <= 10; i++) {
			System.out.println("執行緒一正在輸出:" + i);

		}
	}
}

public class Example2 {
	public static void main(String[] args) throws Exception {
         // 建立一個執行緒
		new Thread(new SleepThread()).start();
		for (int i = 1; i <= 10; i++) {
			if (i == 5) {
				System.out.println("主執行緒暫時休眠500毫秒,接下來是執行緒一輸出");
				Thread.sleep(2000);  // 當前執行緒休眠2秒
			}
			System.out.println("主執行緒正在輸出:" + i);
		}
	}
}
結果:

執行緒休眠只是讓該執行緒停一段時間,一段時間之後就可以接著進行,不需要別的執行緒進行完,例子中因為執行緒一總執行時間較短,在主執行緒休眠的時間內就執行完了。

三、執行緒讓步

通過yield()方法,將當前程序停下,換成就緒狀態,讓系統的排程器重新排程一次。

與sleep()方法相似,但yield()方法不會阻塞該執行緒,之後該執行緒與其他執行緒是相對公平的。排程誰看系統,有可能還是排程它自己。

class YieldThread extends Thread {
    // 定義一個有參的構造方法
	public YieldThread(String name) { 
		super(name); // 呼叫父類的構造方法
	}
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println(Thread.currentThread().getName() + "---" + i);
			if (i == 3) {
				System.out.print("執行緒讓步:\n");
				Thread.yield(); // 執行緒執行到此,作出讓步
			}
		}
	}
}
public class Example2 {
	public static void main(String[] args) {
        // 建立兩個執行緒
		Thread t1 = new YieldThread("執行緒A");
		Thread t2 = new YieldThread("執行緒B");
        // 開啟兩個執行緒
		t1.start();
		t2.start();
	}
}
結果:

通過結果可以看到執行緒讓步之後,有可能系統排程的是別的執行緒,有可能還是自己。

四、執行緒插隊

就像它的名字,插隊,通過join()方法,阻塞當前執行緒,先完成被join()方法加入的插入的這個執行緒,之後再完成其他執行緒。

class EmergencyThread implements Runnable {
	public void run() {
		for (int i = 1; i < 7; i++) {
			System.out.println(Thread.currentThread().getName()+"輸出:"+i);
		}
	}
}

public class Example2{
	public static void main(String[] args) throws Exception {
		// 建立執行緒
		Thread t = new Thread(new EmergencyThread(),"執行緒一");
		t.start(); // 開啟執行緒
		for (int i = 1; i < 7; i++) {
			System.out.println(Thread.currentThread().getName()+"輸出:"+i);
			if (i == 2) {
				//System.out.println("執行緒1插隊");
				t.join(); // 呼叫join()方法
			}
		}
	}
}
結果:

從結果可以看到,當main執行緒輸出2以後,執行緒一就開始執行,直到執行緒一執行完畢,main執行緒才繼續執行。

相關推薦

Java多執行執行排程

(一)執行緒優先順序 執行緒優先順序用1~10表示,10表示優先順序最高,預設值是5.每個優先順序對應一個Thread類的公用靜態常量。如 public static final int MIN_PRIORITY = 1; public static final int NO

最簡單易懂的RxJava2.0學習教程之RxJava2的執行排程

一、RxJava2執行緒排程 使用RxJava的時候,在沒有切換執行緒的情況下, 上游(observable)和下游(observer)是工作在同一個執行緒中的,即都在主執行緒中。 話不多說上程式碼: Observable<Integer>

eclipse執行速度優化解決狂讀盤、釋出慢、CPU100%等問題

我的ECLIPSE執行時速度奇慢,具體表現為: 1、只要ECLIPSE啟動後,硬碟燈就狂閃,不停的讀盤; 2、釋出TOMCAT經常在0%; 3、偶爾CPU佔滿; 網上講優化的文章無數,但是總是有用的卻很少,大部分是轉載甚至是抄襲的。在借鑑各個文章的做法並不斷嘗試後

執行排程執行休眠執行讓步執行插隊

程式中的多個執行緒是併發執行的,某個執行緒若想被執行必須要得到CPU的使用權,Java虛擬機器會按照特定的機制為程式中的每個執行緒分配CPU的使用權,這種機制被稱作執行緒的排程。兩種執行緒排程模式:分時

下列關於執行排程的敘述中錯誤的是。----阿里巴巴2015校招研發線上

下列關於執行緒排程的敘述中,錯誤的是()。 正確答案: B E   你的答案: A E F (錯誤) 呼叫執行緒的sleep()方法,可以使比當前執行緒優先順序低的執行緒獲得執行機會 呼叫執行緒的yeild()方法,只會使與當前執行緒相同優先順序的執行緒

Windows核心程式設計筆記5----執行排程優先順序

1、作業系統執行緒排程過程 每個執行緒都有一個上下文CONTEXT結構體,儲存線上程的核心物件中,這個上下文中儲存了執行緒上一次執行時CPU暫存器的狀態。每隔固定時間,Windows會檢視所有當前存在的執行緒核心物件,其中只有一些是可排程的。Windows在可排程的執行緒中

C# 解決子執行不能操作主執行UI介面問題涉及到多執行的概念。

1、在預設情況下,C#不准許在一個執行緒中直接訪問或操作另一執行緒中建立的控制元件,這是因為訪問windows窗體控制元件本質上是不安全的。 2、執行緒之間是可以同時執行的,那麼如果有兩個或多個執行緒同時操作某一控制元件的某狀態,嘗試將一個控制元件變為自己需要的狀態時, 執行緒的死鎖就可能發生。

如何實現自己的執行不看後悔一看必懂

首先,在服務啟動的時候,我們可以啟動好幾個執行緒,並用一個容器(如執行緒池)來管理這些執行緒。當請求到來時,可以從池中取一個執行緒出來,執行任務(通常是對請求的響應),當任務結束後,再將這個執行緒放入池中備用;如果請求到來而池中沒有空閒的執行緒,該請求需要排隊等候。最後,當服務關閉時銷燬該池即可

java中常見的執行不看後悔一看必懂

Executor介面表示執行緒池,它的execute(Runnable task)方法用來執行Runnable型別的任務,ExecutorService是Executor的子介面,聲明瞭管理執行緒池的一些方法 Java.util.concurrent.Executors類包含了一些靜態

並行JUC併發賣票執行通訊生產者消費者問題

併發和並行 併發: 多個執行緒搶一份資源。比如說12306 搶票。 並行:泡方便麵。正常追求效率的情況下,撕調料包的情況下,燒熱水。比如說一個人執行了多個任務,在聽歌的時候走路。 關於兩者的區別關注下面的這個連線: The Differences 併發會引發的問

Python基礎--- Python多執行介紹開啟執行的三種方式time模組joinDaemonLock、Rlock事件機制Timer

一、多執行緒介紹 --------------------------------------------------------- 1.threading用於提供執行緒相關的操作,執行緒是應用程式中工作的最小單元。 2.python當前版本的多執行緒庫沒有實現優先順序、執行緒組,執

Java之多執行安全屌絲版兩大解決思路要麼不去競爭開闢執行副本、要麼有順序的競爭資源用鎖規定執行秩序

0、多執行緒安全,如果多個執行緒操作一個變數,每次都能達到預期的結果,那麼說明當前這個類起碼是執行緒安全的,我這白話的,可能有點噁心。   1、看看牛人是怎麼說的,為什麼多執行緒併發是不安全的? 在作業系統中,執行緒是不再擁有資源的,程序是擁有資源的。而執行緒是由程序建立的

Web應用啟動時後臺自動啟動一個執行

原文:http://blog.sina.com.cn/s/blog_6810dfc20101ipzq.html Web應用啟動時,後臺自動啟動一個執行緒   (1)前言     前幾天,manager問道一個問題:能不能實現類似於cro

個人對於執行安全的理解內容會不斷更新只是個人理解不具備權威性

多執行緒操作同一資源,如果資源存在狀態,那麼就會引發執行緒安全的問題 以下為個人瞭解的部分解決執行緒安全問題的一些方法 1.使操作的資源具有不可變性 例如使用final修飾,資源變為常量 2.使用多例模式,使用區域性變數 每個物件都是不同的,操作的區域性變數也是獨一份的,就

xtrabackup壓縮備份多執行備份lz4pigz全詳解

常用備份: 目前較新的:percona-xtrabackup-2.4.11-1.el6.x86_64.rpm 配置percona的yum源。 yum install epel-release yum install libev qpress yum install perl

安卓開發筆記—— HttpURLConnection請求訪問Web服務解析JSON資料執行CardView佈局技術bilibili的使用者視訊資訊獲取軟體

中山大學資料科學與計算機學院本科生實驗報告 (2018年秋季學期) 一、實驗題目 WEB API 第十四周實驗目的 學會使用HttpURLConnection請求訪問Web服務 學習Android執行緒機制,學會執行緒更新UI 學會解析JSO

一個很奇葩的併發單鏈表不知道為什麼併發執行上1000就會報錯500以內就很正常

貼程式碼,如果有知道原因的高手希望可以告訴我一下,謝謝 #include <mutex>//互斥鎖 #include <stdio.h>      #include <string>      #include <WINSOC

jdk8新特性Lambda表示式結合spring 執行一行程式碼實現多執行

1.配置spring 執行緒池 @Configuration @EnableAsync @ConfigurationProperties(prefix="threadpool") public class ExecutePoolConfiguration { @V

執行程式設計——面試題每個執行只打印一種字元多個執行協同順序列印n次字串求大神的其他實現方案

(這個是歡聚時刻(YY)的筆試題,在筆試的時候沒有寫出來,後來自己寫了出來,希望大神能給出更優秀的解決方案……ps:現在面試官總有面試時問筆試程式設計題思路的習慣,呵呵) 題目簡述: 輸入一個字串以

當一個類被載入後它的靜態變數生命週期是什麼是整個應用程式執行結束比如java web程式從類載入到伺服器關閉還是該執行執行完畢還是別的什麼?

靜態變數在記憶體中只有一個,JAVA虛擬機器載入類的時候為其分配記憶體,位於方法區,被類的所有例項共享,其生命週期取決於類的生命週期。。。當類被解除安裝。。。靜態變數也被銷燬 取決於類載入器。如果換了一個類載入器,這個