Java并發篇_線程詳解

線程(thread) 是操作系統能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以并發多個線程,每條線程并行執行不同的任務。

一、線程的分類

我們知道計算機可以分為硬件和軟件兩大塊,硬件是基礎,軟件提供實現不同功能的手段;而軟件又可以分為操作系統和應用程序,操作系統專注于對硬件的交互管理并提供一個運行環境給應用程序使用,應用程序則是能實現若干功能的并且運行在操作系統環境中的軟件。

同樣,線程按照操作系統和應用程序兩層次可以分為內核線程(Kernel-Level Thread)和用戶線程(User Thread)。

  • 內核線程(Kernel-Level Thread,KLT) 就是直接由操作系統內核(Kernel,下稱內核)支持的線程,這種線程由內核來完成線程切換
  • 用戶線程(User Thread,UT) 從廣義上來講,一個線程只要不是內核線程,就可以認為是用戶線程;而狹義上的用戶線程指的是完全建立在用戶空間的線程庫上,系統內核不感知線程存在的實現。用戶線程的建立、同步、銷毀和調度完全在用戶態中完成,不需要內核的幫助

二、Java線程的實現

Java創建線程的兩種方式:實現Runnable接口,繼承Thread類

  • 實現Runnable接口:寫一個類實現Runnable接口,實現里面的run方法,用new Thread(Runnable target).start()方法來啟動
    1. 增強了程序的健壯性,代碼能夠被多個線程共享,代碼與數據是獨立的
    2. 線程體run()方法所在的類還可以從其他類繼承一些有用的屬性和方法,避免了由于Java的單繼承特性帶來的局限
    3. 有利于保持程序風格的一致性
  • 繼承Thread類:寫一個類繼承自Thread類,然后重寫里面的run方法,用start方法啟動線程
    1. Java中只支持單繼承,Thread子類無法再從其他類繼承
    2. 編寫簡單,run()方法的當前對象就是線程對象,可直接操縱

三、Java的線程優先級

Java使用的線程調度方式就是搶占式調度

雖然Java線程調度是系統自動完成的,但是我們還是可以“建議”系統給某些線程多分配一點執行時間,另外的一些線程則可以少分配一點——這項操作可以通過設置線程優先級來完成。

Java語言一共設置了10個級別的線程優先級(Thread.MIN_PRIORITY至Thread.MAX_PRIORITY),在兩個線程同時處于Ready狀態時,優先級越高的線程越容易被系統選擇執行。不過,線程優先級并不是太靠譜,原因是Java的線程是通過映射到系統的原生線程上來實現的,所以線程調度最終還是取決于操作系統,雖然現在很多操作系統都提供線程優先級的概念,但是并不見得能與Java線程的優先級一一對應,如Solaris中有2147483648(232)種優先級,但Windows中就只有7種,比Java線程優先級多的系統還好說,中間留下一點空位就可以了,但比Java線程優先級少的系統,就不得不出現幾個優先級相同的情況了

下圖顯示了Java線程優先級與Windows線程優先級之間的對應關系,Windows平臺的JDK中使用了除THREAD_PRIORITY_IDLE之外的其余6種線程優先級。

Java線程優先級Windows線程優先級
1. Thread.MIN_PRIORITYTHREAD_PRIORITY_LOWEST
2.THREAD_PRIORITY_LOWEST
3.THREAD_PRIORITY_BELOW_NORMAL
4.THREAD_PRIORITY_BELOW_NORMAL
5. Thread.NORM_PRIORITYTHREAD_PRIORITY_NORMAL
6.THREAD_PRIORITY_ABOVE_NORMAL
7.THREAD_PRIORITY_ABOVE_NORMAL
8.THREAD_PRIORITY_HIGHEST
9.THREAD_PRIORITY_HIGHEST
10. Thread.MAX_PRIORITYTHREAD_PRIORITY_CRITICAL

其實,即使設置了線程的優先級,一樣無法確保這個線程一定先執行,因為它有很大的隨機性。它并無法控制執行哪個線程,因為線程的執行,是搶占資源后才能執行的操作,而搶占到資源時,最多是給于線程優先級較高的線程一點機會而已,能不能抓住可是不一定的。

說到底就一句話:線程優化級較高的線程不一定先執行

四、Java線程生命周期

線程的生命周期包含5個階段,包括:新建、就緒、運行、阻塞、銷毀。

  • 新建:就是剛使用new方法,new出來的線程;
  • 就緒:就是調用的線程的start()方法后,這時候線程處于等待CPU分配資源階段,誰先搶的CPU資源,誰開始執行;
  • 運行:當就緒的線程被調度并獲得CPU資源時,便進入運行狀態,run方法定義了線程的操作和功能;
  • 阻塞:在運行狀態的時候,可能因為某些原因導致運行狀態的線程變成了阻塞狀態,比如sleep()、wait()之后線程就處于了阻塞狀態,這個時候需要其他機制將處于阻塞狀態的線程喚醒,比如調用notify或者notifyAll()方法。喚醒的線程不會立刻執行run方法,它們要再次等待CPU分配資源進入運行狀態;
  • 銷毀:如果線程正常執行完畢后或線程被提前強制性的終止或出現異常導致結束,那么線程就要被銷毀,釋放資源;

完整的生命周期圖如下:

? img

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/535677.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/535677.shtml
英文地址,請注明出處:http://en.pswp.cn/news/535677.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

修改MYSQL最大連接數的3種方法

MYSQL數據庫安裝完成后,默認最大連接數是100,一般流量稍微大一點的論壇或網站這個連接數是遠遠不夠的,增加默認MYSQL連接數的方法有兩個 方法一:進入MYSQL安裝目錄 打開MYSQL配置文件 my.ini 或 my.cnf查找 max_connections100 …

可擴展的編程語言——Scala

一、Scala是什么 Scala是一種多范式的編程語言,其設計的初衷是要集成面向對象編程和函數式編程的各種特性。Scala運行于Java平臺(Java虛擬機),并兼容現有的Java程序。 ? Scala語言的名稱來自于"可伸展的語言"。之所以…

ubuntu7.10 apache+php+mysql配置

本篇文章 經過許多次的測試和修改已經完成了在Ubuntu7.10 下 安裝配置 ApachePHPMySQL的所有的工作. 1、在Ubuntu7.10 下安裝 Apache2PHP5MySQL sudo apt-get install apache2 libapache2-mod-php5 php5 php5-gd mysql-server php5-mysql phpmyadmin在下載來自動安裝配置的時候…

Spark-大規模數據處理計算引擎

官網:http://spark.apache.org 一、Spark是什么 Spark是一種快速、通用、可擴展的大數據分析引擎,2009年誕生于加州大學伯克利分校AMPLab,2010年開源,2013年6月成為Apache孵化項目,2014年2月成為Apache頂級項目。項目是…

MySQL Replace INTO的使用

REPLACE的運行與INSERT很相像。只有一點除外,如果表中的一個舊記錄與一個用于PRIMARY KEY或一個UNIQUE索引的新記錄具有相同的值,則在新記錄被插入之前,舊記錄被刪除。請參見13.2.4節,“INSERT語法”。 注意,除非表有…

CentOS7下Spark集群的安裝

從物理部署層面上來看,Spark主要分為兩種類型的節點,Master節點和Worker節點,Master節點主要運行集群管理器的中心化部分,所承載的作用是分配Application到Worker節點,維護Worker節點,Driver,Ap…

Scala中class與object區別

calss scala編譯器會字段幫我們生產一個私有字段和2個公有方法get和set scala 中沒有 static 關鍵字,所以 對于一個class來說,所有的方法和成員變量在實例被 new 出來之前都是無法訪問的 因此在class中的main方法沒什么用了 scala 的object 中所有成員…

如何編寫一個shell腳本

本文結合大量實例闡述如何編寫一個shell腳本。 為什么要進行shell編程 在Linux系統中,雖然有各種各樣的圖形化接口工具,但是sell仍然是一個非常靈活的工具。Shell不僅僅是命令的收集,而且是一門非常棒的編程語言。您可以通過使用shell使大量的…

Scala變量和常用數據類型

一、 聲明值和變量 Scala聲明變量有兩種方式,一個用val,一個用var。 聲明方式:val / var 變量名 : 變量類型 變量值 val定義的值是不可變的,它不是一個常量,是不可變量,或稱之為只讀變量。 val示例&am…

ubuntu7.10下的vi用的怪怪的

到網上查了一下,原來是ubuntu7.10默認安裝的是vim-tiny.可以重新安裝vim-full #dpkg -l 如果是vim-tiny #apt-get install vim-full

(轉)JVM監控工具介紹

2008年03月04日 16:57原作者: stone2083 原文地址:http://www.blogjava.net/stone2083/archive/2008/02/25/182081.htmljstatd啟動jvm監控服務。它是一個基于rmi的應用,向遠程機器提供本機jvm應用程序的信息。默認端口1099。實例:…

Scala的控制結構

一、 if else表達式 scala中沒有三目運算符,因為根本不需要。scala中if else表達式是有返回值的,如果if或者else返回的類型不一樣,就返回Any類型(所有類型的公共超類型)。 例如:if else返回類型一樣 scal…

【Kubernetes】控制器Statefulset

Statefulset控制器 一、概念二、Statefulset資源清單文件編寫技巧2.1、查看定義Statefulset資源需要的字段2.2、查看statefulset.spec字段如何定義2.3、查看statefulset的spec.template字段如何定義 三、Statefulset使用案例:部署web站點3.1、編寫一個Statefulset資…

Scala 函數

scala定義函數的標準格式為: def 函數名(參數名1: 參數類型1, 參數名2: 參數類型2) : 返回類型 {函數體} 函數示例1:返回Unit類型的函數 def shout1(content: String) : Unit {println(content) }函數示例2:返回Unit類型的函數&#xff0…

ubuntu7.10中的apache的一些設置

在/etc/apache2/mods-available目錄下是apache2可用的模塊.出現在這里的模塊不代表你可以用.只是表明你的apache2已經安裝了這些模塊.可用的模塊在/etc/apache2/mods-enabled這個目錄下.(從redhat系列轉過來看ubuntu,雖然感覺不習慣,但覺得ubuntu的這種分目錄的方法很不錯.) 如…

Java并發篇_Java內存模型

在并發編程中,我們通常會遇到以下三個問題:原子性問題,可見性問題,有序性問題。那么它們產生的原因和在Java中解決的辦法又是什么呢? 一、內存模型的相關概念 ? 計算機在執行程序時,每條指令都是在CPU中執…

rz的安裝

以前,在redhat系列的linux中,通過終端工具操作服務器,經常使用rz來上傳小文件.但是有些系統默認情況下不能使用此命令.今天通過ubuntu.看到這條命令.即使ubunt沒有裝這個命令,你輸入此命令時,它會提示你進行安裝. rootubuntu:~# rzThe program rz is currently not installed. …

Java并發篇_synchronized

synchronized是Java語言的關鍵字,當它用來修飾一個方法或者一個代碼塊的時候,能夠保證在同一時刻最多只有一個線程執行該段代碼。本文給大家介紹java中的用法。 一、為什么要使用synchronized 在并發編程中存在線程安全問題,主要原因有&…

mysqlreport的學習

mysqlreport是一個腳本. 需要先安裝perl-DBI和perl-DBD-MySQL這2個包 mysqlreport 使用DBI 需要有http://hackmysql.com/mysqlreportdocperl ./mysqlreport --help 看幫助 perl ./mysqlreport --user root --password 密碼mysqlreport 文檔mysqlreport 以很友好的方式顯示 My…

Java并發篇_volatile

volatile是Java提供的一種輕量級的同步機制。Java 語言包含兩種內在的同步機制:同步塊(或方法)和 volatile 變量,相比于synchronized(synchronized通常稱為重量級鎖),volatile更輕量級&#xff…