【JAVA基礎篇】多線程

學習Java的多線程知識之前,我們先來了解一下進程和線程的概念,以及他們之間的關系。

進程

基本概念

進程是具有獨立功能的程序在某個數據集合上的一次執行過程。

特點

  1. 進程是操作系統進行資源分配的基本單位。
  2. 每個進程都有自己的地址空間,即進程空間。

線程

基本概念

一個進程內部的一個執行單元,它是程序中的一個單一的順序控制流程。

特點

  1. 自己不擁有系統資源,只擁有一點兒在運行過程中必不可少的資源。與同一個進程下的其他所有線程共享進程所擁有的全部資源。
  2. 線程是進程中的一個實體,是被操作系統獨立調度的基本單位。

進程和線程的聯系和區別

進程是資源分配的基本單位,線程是調度的基本單位。進程包含線程,線程共用進程的資源。

Java實現多線程

有四種方式:

  1. 繼承Thread類
  2. 實現Runnable接口
  3. 實現Callable接口,并與FutureTask結合使用
  4. 線程池

繼承Thread類

package com.cc.thread;public class ThreadDemo extends Thread{public ThreadDemo(String name) {super(name);}@Overridepublic void run() {for (int i = 0; i < 10000; i++) {System.out.println(this.getName()+i);}}public static void main(String[] args) {new ThreadDemo("張三").start();new ThreadDemo("李四").start();}}

實現Runnable接口

package com.cc.thread;public class RunableDemo implements Runnable {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public RunableDemo(String name) {super();this.name = name;}@Overridepublic void run() {for (int i = 0; i < 10000; i++) {System.out.println(this.getName()+i);}}public static void main(String[] args) {new Thread(new RunableDemo("張三")).start();new Thread(new RunableDemo("李四")).start();}}

實現Callable接口,并與FutureTask結合使用

package com.cc.thread;import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class CallableDemo {public static void main(String[] args) {CallableImpl callableImpl = new CallableImpl();FutureTask<Integer> futureTask = new FutureTask<Integer>(callableImpl);Thread thread = new Thread(futureTask);thread.start();try {int sum = futureTask.get();System.out.println(sum);} catch (InterruptedException | ExecutionException e) {e.printStackTrace();}}private static class CallableImpl implements Callable<Integer>{@Overridepublic Integer call() throws Exception {int sum = 0;for (int j = 0; j <= 100; j++) {System.out.println(Thread.currentThread().getName()+":"+j);sum += j;}return sum;}}}

運行上面的代碼,我們發現每次返回的結果都是5050(這么巧的嗎?難道每次call方法瞬間就執行完了,然后再執行的int sum = futureTask.get();),其實如果線程的call方法還未執行完畢,futureTask.get()方法會一直阻塞,直到call()方法執行完畢才能取到返回值。

線程的生命周期

通過查看Thread內部類State的源碼,我們知道線程有6中狀態,分別是:

? ? NEW,
? ? RUNNABLE,
? ? BLOCKED,
? ? WAITING,
? ? TIMED_WAITING,
? ? TERMINATED;

Thread內部類State的源碼

    public enum State {/*** Thread state for a thread which has not yet started.*/NEW,/*** Thread state for a runnable thread.  A thread in the runnable* state is executing in the Java virtual machine but it may* be waiting for other resources from the operating system* such as processor.*/RUNNABLE,/*** Thread state for a thread blocked waiting for a monitor lock.* A thread in the blocked state is waiting for a monitor lock* to enter a synchronized block/method or* reenter a synchronized block/method after calling* {@link Object#wait() Object.wait}.*/BLOCKED,/*** Thread state for a waiting thread.* A thread is in the waiting state due to calling one of the* following methods:* <ul>*   <li>{@link Object#wait() Object.wait} with no timeout</li>*   <li>{@link #join() Thread.join} with no timeout</li>*   <li>{@link LockSupport#park() LockSupport.park}</li>* </ul>** <p>A thread in the waiting state is waiting for another thread to* perform a particular action.** For example, a thread that has called <tt>Object.wait()</tt>* on an object is waiting for another thread to call* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on* that object. A thread that has called <tt>Thread.join()</tt>* is waiting for a specified thread to terminate.*/WAITING,/*** Thread state for a waiting thread with a specified waiting time.* A thread is in the timed waiting state due to calling one of* the following methods with a specified positive waiting time:* <ul>*   <li>{@link #sleep Thread.sleep}</li>*   <li>{@link Object#wait(long) Object.wait} with timeout</li>*   <li>{@link #join(long) Thread.join} with timeout</li>*   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>*   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>* </ul>*/TIMED_WAITING,/*** Thread state for a terminated thread.* The thread has completed execution.*/TERMINATED;}

?關于線程狀態的詳細描述和他們之前的相互轉換請參考4 Java線程的狀態及主要轉化方法 · 深入淺出Java多線程

線程方法總結

start使線程由新建狀態進入就緒狀態,只能調用一次,否則會報IllegalThreadStateException
run線程執行體,由系統調用
isAlive新建和死亡狀態會返回false,其他狀態返回true
interrupt設置線程中斷狀態為true
interruptedstatic方法,先返回當前線程中斷狀態,然后設置線程中斷狀態為false
isInterrupted返回當前線程中斷狀態
sleepstatic native方法,使線程進入阻塞狀態(不會釋放同步鎖)
currentThreadstatic方法,該方法返回當前正在使用CPU資源的線程
setPriority

final方法,設置線程的優先級,1~10 1最低 10最高 5是默認值

線程的優先級具有繼承性,比如A線程啟動B線程,則A和B的線程優先級是一樣的

getPriorityfinal方法,獲取線程優先級
setDaemon設置守護線程(也叫服務線程,用于為系統中的對象和線程提供服務,如果都是服務線程,那么JVM結束,垃圾回收線程是守護線程)
isDaemon判斷是否是守護線程
jointhread1.join();使當前線程進入阻塞狀態,thread1線程執行完后,再喚醒當前線程
yeild使當前線程進入就緒狀態
waitObject類的方法,讓當前線程進入阻塞狀態,并且釋放它持有的同步鎖
notifyObject類的方法,喚醒一個阻塞狀態的線程
notifyAllObject類的方法,喚醒所有阻塞狀態的線程

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

join方法的使用

package com.cc.thread;public class ThreadJoin {public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread("線程1"){@Overridepublic void run() {for (int i = 0; i < 1000; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}};thread1.start();thread1.join();for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+":"+i);}}}

interrupt、interrupted和isInterrupted的作用和區別

  1. interrupt設置線程中斷狀態為true
  2. interrupted先返回當前線程中斷狀態,然后設置線程中斷狀態為false
  3. isInterrupted返回當前線程中斷狀態
  4. 下面的demo只用到了sleep方法,wait,join方法類似于sleep
package com.cc.thread;public class InterruptTest {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(){@Overridepublic void run() {for (int i = 0; i < 5; i++) {try {sleep(2000);//線程默認中斷狀態為false,調用sleep方法,或者在sleep的過程中,當中斷狀態為true時,執行sleep會拋出異常interrupt();//設置中斷狀態為true} catch (InterruptedException e) {//拋出異常后中斷狀態自動設置為falseSystem.out.println("出現中斷異常,中斷狀態:"+isInterrupted());}System.out.println("正常執行,中斷狀態:"+isInterrupted());}}};thread.start();}}
package com.cc.thread;public class InterruptTest {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(){@Overridepublic void run() {for (int i = 0; i < 5; i++) {try {sleep(2000);//線程默認中斷狀態為false,調用sleep方法,或者在sleep的過程中,當中斷狀態為true時,執行sleep會拋出異常interrupt();//設置中斷狀態為trueSystem.out.println("interrupted方法:"+interrupted());//此函數首先返回當前的中斷狀態,然后將中斷狀態置為falseSystem.out.println("isInterrupted:"+isInterrupted());} catch (InterruptedException e) {//拋出異常后中斷狀態自動設置為falseSystem.out.println("出現中斷異常,中斷狀態:"+isInterrupted());}System.out.println("正常執行,中斷狀態:"+isInterrupted());}}};thread.start();}}

wait方法的使用

package com.cc.thread;public class ObjectWait {public static void main(String[] args) {try {Thread threadTest = new Thread(){public void run(){System.out.println("執行線程中方法");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}};threadTest.start();synchronized(threadTest){threadTest.wait();		//當線程終止的時候,會調用線程自身的notifyAll()方法}System.out.println("執行到了這里");} catch (InterruptedException e) {e.printStackTrace();}}
}

synchronized

synchronized的用法參考Java中使用同步關鍵字synchronized需要注意的問題 - @ 小浩 - 博客園

synchronized是非公平鎖

synchronized的實現原理參考Java中的鎖——Lock和synchronized - 夏末秋涼 - 博客園

?1,synchronized代碼塊基于進入和退出monitor對象實現。代碼編譯后將monitorenter指令插入同步代碼塊的前面,monitorexit指令插入同步代碼塊的后面,發生異常時也會執行monitorexit指令

2,synchronized方法讀取運行時常量池中方法的?ACC_SYNCHRONIZED?標志來隱式實現的

3,synchronized用的鎖存儲在對象頭中的markword,markword中的鎖標記指向的是monitor對象,

鎖標記位(無鎖01、輕量級鎖00、重量級鎖10、偏向鎖01)

4,monitor對象有兩個隊列(EntryList、WaitSet)以及鎖持有者Owner標記

線程安全的概念

什么是線程安全:在多線程環境下,線程安全的代碼會通過線程同步機制保證各個線程可以正常的正確的執行,不會出現數據污染等意外情況。

什么是線程同步:是指各個線程按照一定的順序執行

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

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

相關文章

配置JAVA開發環境

1、首先去Oracle官方網站下載所需版本的JDKhttp://java.sun.com/products/archive/&#xff0c;然后安裝&#xff0c;其實只需要安裝jdk就可以了&#xff0c;不需要安裝jre 2、按照后配置環境變量JAVA_HOME 然后在path最前面添加%JAVA_HOME%\bin; 3、cmd中輸入java -version,提…

【JAVA基礎篇】枚舉

/*** 一組相同類型的常量的集合* author cc**/ public class EnumDemo {public static void main(String[] args) {//遍歷for(WorkDay workDay:WorkDay.values()){System.out.println("序號&#xff1a;"workDay.ordinal());//ordinal&#xff0c;返回枚舉常量的序號…

【JAVA基礎篇】集合框架

一、集合框架圖 Java集合框架主要包含兩種類型的容器&#xff0c;一是集合(Collection)&#xff0c;存儲元素集合&#xff0c;二是圖(Map)&#xff0c;存儲鍵(key)-值(value)對.Collection接口下面有兩個重要的子接口List和Set&#xff0c;再下面是一些抽象類&#xff0c;最后是…

【JAVA基礎篇】對象初始化過程

我們都知道&#xff0c;創建對象是由 new關鍵字調用構造方法 返回類實例&#xff08;實際上還可以通過反射來創建實例&#xff09;。 例如 : Person jack new Person(); 這句話到底做了什么事情呢 &#xff1f; 其實就是講對象的初始化過程。 1、 new 用到了Person.class,所…

【Java基礎篇】try catch finally語句包含return語句時的執行過程

網上有很多人探討Java中異常捕獲機制try…catch…finally塊中的finally語句是不是一定會被執行&#xff1f; 很多人都說不是&#xff0c;當然他們的回答是正確的&#xff0c;經過我試驗&#xff0c;至少有兩種情況下finally語句是不會被 try語句沒有被執行到&#xff0c;如在…

eclipse指定JDK版本啟動,解決version XXX of the JVM is not suitable for this product.Version:XXX 問題

問題描述&#xff1a;啟動eclipse時&#xff0c;提示version 1.7.0 of the JVM is not suitable for this product.Version:1.8 or greater is required. 原因分析&#xff1a;原因是我的筆記本安裝了多個JDK版本&#xff0c;但是現在我的JAVA_HOME配置的是jdk1.7的路徑&#x…

【JAVA基礎篇】Socket編程

一、Socket的概念 Socket是一種通訊機制&#xff0c;通常稱為套接字。英文原意是插座&#xff0c;顧明思義&#xff0c;Socket像是一個多孔插座&#xff0c;可以提供多個端口的連接服務 ps:至于socket在計算機術語中怎么就翻譯成了“套接字”這個令人費解的詞&#xff0c;這真…

【JAVA基礎篇】注解

一、什么是注解&#xff1f; 注解是元數據&#xff0c;所謂元數據就是描述數據的數據。 在annotation誕生之前&#xff08;jdk1.5誕生了注解&#xff09;&#xff0c;甚至之后&#xff0c;xml被廣泛的由于描述元數據。但是后來&#xff0c;有一些應用開發工程師和架構師覺得它…

【JAVA基礎篇】IO流

一、流的概念 “對語言設計人員來說&#xff0c;創建好的輸入&#xff0f;輸出系統是一項特別困難的任務。” ――《Think in Java》 無論是系統、還是語言的設計中IO的設計都是異常復雜的。面臨的最大的挑戰一般是如何覆蓋所有可能的因素&#xff0c;我們不僅僅要考慮文件、…

SpringMVC注解

一&#xff0c;RequestMapping 可以用在類和方法上 1.1 作用&#xff1a; 將客戶端請求映射到可匹配的類和方法中 1.2 屬性&#xff1a; name 給映射指定一個名字 path(同value相同&#xff09; 請求的url&#xff0c;path{"/mixedAttribute1","/mixedA…

【JAVA基礎篇】運算符

一、表達式 表達式由運算符和操作數組成 例如&#xff1a; 5 num1 num1num2 sumnum1num2 二、運算符分類 算數運算符、賦值運算符、關系運算符、邏輯運算符、條件運算符、位運算符 三、算數運算符 四、賦值運算符 格式&#xff1a;變量表達式 例如&#xff1a;int n3…

a4紙網頁打印 table_打印模板不愁人,你還在打印單調的A4紙嗎?

軟件介紹早在幾年前&#xff0c;社會上就已經開始了數字化、無紙化的推廣&#xff0c;但是就算再怎么無紙化&#xff0c;紙張還是有它必要的存在&#xff0c;在工作、學習過程中&#xff0c;打印的需求也必不可少的。但是一般的打印都是比較平庸的&#xff0c;要做會議記錄&…

IP地址、子網掩碼、網關、默認網關、DNS的理解

IP地址 Internet上為了區分數以億計的主機而給每個主機分配一個專門的地址&#xff0c;通過IP地址可以訪問到每臺主機。 子網掩碼 子網掩碼又稱網絡掩碼、地址掩碼、子網絡遮罩。它是用來指明一個IP地址哪些位標識的是主機所在的子網&#xff0c;以及哪些位標識的是主機的位…

上證指數30年k線圖_技術預判2020:上證指數要突破3500點才會“井噴”

2019年的行情很快就要收官了&#xff0c;截止目前&#xff0c;上證指數今年的漲幅是20.5%&#xff0c;不過可能有部分投資者今年的收益率還沒達到大盤指數的平均水平。不管怎樣&#xff0c;今年很快就要翻篇了&#xff0c;關鍵是看2020年股市能不能迎來更好的行情了。而總結得失…

【JAVA基礎篇】基本數據類型及自動類型轉換

一、8種基本數據類型以及占用內存空間大小 boolean 1byte或4byte byte 8bit/1byte char 16bit/2byte short 16bit/2byte float 32bit/4byte int 32bit/4byte long 64bit/8byte double 64bit/8byte 二、自動類型轉換 …

的優缺點_淺談桉木家具的優缺點

家具現在的材質是有很多的&#xff0c;木質的&#xff0c;石材的&#xff0c;還有真空充氣的&#xff0c;都是很不錯的類型。桉木家具是現在很多人都喜歡的一種材質&#xff0c;但是很多人對桉木家具的優缺點不是很清楚&#xff0c;為了能夠讓大家更加清楚的了解桉木家具&#…

【算法篇】遞歸

一、遞歸的概念 程序調用自身的編程技巧稱為遞歸。 遞歸的核心思想就是將一個大規模復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解。 二、遞歸的優點 使用遞歸的好處是只需要少量的代碼就可以描述出求解問題過程中多次重復的計算&#xff0c;大大減少了程序…

客戶說發貨慢怎么回復_女生微信說身體不舒服怎么回復關心她?

當你不在女生身邊&#xff0c;女生微信給你說身體不舒服&#xff0c;肯定需要說點話來安慰她了。多喝熱水肯定是不行了&#xff0c;一點用處都沒有&#xff0c;還會讓女生覺得你根本不重視她&#xff0c;是在敷衍她&#xff0c;那女生微信說身體不舒服怎么回復關心她呢&#xf…

【算法篇】八種內排序算法

常用的八種內排序算法分別是&#xff1a; 交換排序&#xff1a;冒泡排序、快速排序選擇排序&#xff1a;簡單選擇排序、堆排序插入排序&#xff1a;直接插入排序、希爾排序歸并排序基數排序 內排序巧記&#xff1a;選(選擇)艦(簡單選擇)隊(堆)的時候腳(交換)毛(冒泡)快(快速)&…

數據分析專題報告范文6篇_小學生看圖寫話范文:小熊玩蹺蹺板?(6篇),讓孩子參考練習...

?范文01&#xff1a;小熊蹺蹺板一天&#xff0c;天氣晴朗&#xff0c;胖乎乎的小熊和小白兔一起玩蹺蹺板。小熊一屁股坐在地上&#xff0c;小白兔說&#xff1a;“啊&#xff01;我有恐高癥哇&#xff01;”小熊說&#xff1a;“我比你重&#xff0c;所以你沒有辦法把我翹起來…