【Java】多執行緒基礎
執行緒的狀態
狀態名稱 | 說明 |
---|---|
new | 初始狀態:執行緒被構建,但沒有呼叫start()方法 |
runnable | 執行狀態:就緒和執行統稱“執行中” |
blocked | 阻塞狀態:執行緒阻塞於鎖 |
waiting | 等待狀態:執行緒進入等待狀態,需要等待其他執行緒通知或中斷 |
time_waiting | 超時等待狀態:指定時間自行返回 |
terminated | 終止狀態:執行緒已執行完畢 |
1. 執行緒建立後,呼叫start()開始執行,進入執行狀態;
2. 執行wait()方法後,進入等待狀態;
3. 進入等待狀態的執行緒需要其他執行緒通知才能返回執行狀態;
4. 如果是超時等待狀態,超時後會返回執行狀態;
5. 呼叫同步方式,沒有獲得鎖(synchronized),則進入阻塞狀態;
6. 如果是鎖是Lock介面的,則進入等待狀態;
7. 執行Runnable的run()後,進入終止狀態;
啟動 & 終止
構造執行緒
private void init(String name,ThreadGroup g,Runnable target){
if(name == null){
throw new NullPointerException("name cannot be null")
}
//當前執行緒為父執行緒
Thread parent = currentThread();
this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
this .name = name.toCharArray();
this.target = target;
setPriority(priority);
//複製父執行緒的InheritableThreadLocal
if(parent.inheritableThreadLocals != null){
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
}
//分配執行緒ID
tid = nextThreadID();
}
啟動執行緒:呼叫start()方法即可啟動執行緒
終止執行緒
public static void main(String[] args)throws Exception{
Runner one = new Runner();
Thread countThread = new Thread(one,"CountThread");
countThread.start();
TimeUnit.SECONDS.sleep(1); //睡眠1秒,main執行緒對CountThread進行中斷,使countThread能夠感知中斷而結束
countThread.interrupt();
Runner two = new Runner();
countThread = new Thread(two,"CountThread");
countThread.start();
TimeUnit.SECONDS.sleep(1); //睡眠1秒,main執行緒Runner two進行cancel,使countThread能夠感知on為false而結束
two.cancel();
}
private static class Runner implements Runnable{
private long i;
private volatile boolean on = true;
@Override
public void run(){
while(on && !Thread.currentThread().isInterrupted()){
i++;
}
System.out.println("Count i = " + i);
}
public void cancel(){
on = false;
}
}
執行緒間通訊
等待 / 通知 機制
static boolean flag = true;
static Object lock = new Object();
public static main(String[] args)throws Exception{
Thread waitThread = new Thread(new Wait(),"WaitThread");
waitThread.start();
TimeUnit.SECONDS.sleep(1);
Thread notifyThread = new Thread(new Notify(),"NotifyThread");
notifyThread.start();
}
static class Wait implements Runnable{
public void run(){
synchronized(lock){
while(flag){
try{
System.out.println(Thread.currentThread() + " wait");
lock.wait();
}catch(InterruptedException e){ }
}
System.out.println(Thread.currentThread() + " run");
}
}
}
static class Notity implements Runnable{
public void run(){
synchronized(lock){
System.out.println(Thread.currentThread() + " notify");
lock.notifyAll();
flag = false;
SleepUtils.senond(5);
}
synchronized(lock){
System.out.println(Thread.currentThread() + " hold lock again");
}
}
}
管道輸入 / 輸出流
public static void main(String[] args)throws Exception{
PipedWriter out = new PipedWriter();
PipedReader in = new PipedReader();
out.connect(in);
Thread printThread = new Thread(new Print(in),"PrintThread");
printThread.start();
int receive = 0;
try{
while((receive = System.in.read()) != -1){
out.write(receive);
}
}finally{
out.close();
}
}
static class Print implements Runnable{
private PipedReader in;
public Print(PipedReader in){
this.in = in;
}
public void run(){
int receive = 0;
try{
while((receive = in.read) != -1){
System.out.print((char)receive);
}
}catch(IOException e){ }
}
}
Thread.join()
執行緒A執行thread.join():執行緒A等待thread執行緒終止後才從thread.join()返回
public static void main(String[] args)throws Exception{
Thread previous = Thread.currentThread();
for(int i = 0; i < 10; i++){
Thread thread = new Thread(new Domino(previous),String.valueOf(i));
thread.start();
previous = thread;
}
TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName() + " terminate.");
}
static class Domino implements Runnable{
private Thread thread;
public Domino(Thread thread){
this.thread = thread;
}
public void run(){
try{
thread.join();
}catch(InterruptedException e){ }
System.out.println(Thread.currentThread().getName() + " terminate.");
}
}
ThreadLocal
public class Profiler{
private static final ThreadLocal<long> TIME_THREADLOCAL = new ThreadLocal<long>(){
protected Long initialValue(){
return System.currentTimeMillis();
}
}
public static final void begin(){
TIME_THREADLOCAL.set(System.currentTimeMillis());
}
public static final long end(){
return System.currentTimeMillis() - TIME_THREADLOCAL.get();
}
public static void main(String[] args)throws Exception{
Profiler.begin();
TimeUnit.SECONDS.sleep(1);
System.out.println("Cost: " + Profiler.end() + " mills");
}
}
小結
執行緒的生命週期中有6中不同狀態,指定時刻,只能處在一個狀態;
執行緒的相互配合需要執行緒間的通訊,等待/通知機制可以得到生產者消費者的效果,管道輸入輸出流可以線上程間進行資料傳輸,Thread.join()有等待插入執行緒完成的效果,ThreadLocal是附帶線上程上的變數,可以讓執行緒儲存檢視值
相關推薦
【Java】多執行緒基礎
執行緒的狀態 狀態名稱 說明 new 初始狀態:執行緒被構建,但沒有呼叫start()方法 runnable 執行狀態:就緒和執行統稱“執行中” blocked 阻塞狀態:執行緒阻塞於鎖 waitin
【Java】多執行緒初探
Java的執行緒狀態 從作業系統的角度看,執行緒有5種狀態:建立, 就緒, 執行, 阻塞, 終止(結束)。如下圖所示 而Java定義的執行緒狀態有: 建立(New), 可執行(Runnable), 阻塞(Blocked), 等待(Waiting), 計時等待(Time
【JAVA】多執行緒造成的安全問題
前言 執行緒可以看做我們每一個人,在社會中可能表現出不同的行為,所以人發生的情況執行緒也可能發生。 1.死鎖問題 兩個人吃飯,一雙筷子,一人拿起一根,等待前一個人丟下筷子; 2.飢餓問題 食堂吃飯需要排隊,還可以插隊,於是
【java】多執行緒批量拆分List匯入資料庫
一、前言 前兩天做了一個匯入的功能,匯入開始的時候非常慢,匯入2w條資料要1分多鐘,後來一點一點的優化,從直接把list懟進Mysql中,到分配把list匯入Mysql中,到多執行緒把list匯入Mysql中。時間是一點一點的變少了。非常的爽,最後
【Java】多執行緒系列05(執行緒等待與喚醒)
1、wait(),notify(),notifyAll()等方法介紹 在Object.java中,定義了wait(), notify()和notifyAll()等介面。wait()的作用是讓當前執行緒進入等待狀態,同時,wait()也會讓當前執行緒釋放它
【Java】多執行緒系列(三)之阻塞執行緒的多種方法
前言: 在某些應用場景下,我們可能需要等待某個執行緒執行完畢,然後才能進行後續的操作。也就是說,主執行緒需要等待子執行緒都執行完畢才能執行後續的任務。 例如,當你在計算利用多執行緒執行幾個比較耗時的任務的時候,主執行緒需要利用這幾個執行緒計算的結果,才能進行後
【JAVA】多執行緒之記憶體可見性
多執行緒之記憶體可見性 一、什麼是可見性? 一個執行緒對共享變數值的修改,能夠及時地被其他執行緒所看到。 共享變數:如果一個變數在多個執行緒的工作記憶體中都存在副本,那麼這個變數就是這幾個執行緒的共
Java定時任務Timer排程器【二】 多執行緒原始碼分析(圖文版)
上一節通過一個小例子分析了Timer執行過程,牽涉的執行執行緒雖然只有兩個,但實際場景會比上面複雜一些。 首先通過一張簡單類圖(只列出簡單的依賴關係)看一下Timer暴露的介面。 為了演示Timer所暴露的介面,下面舉一個極端的例子(每一個介面方法面
【python3】多執行緒-執行緒同步
- 1. 認識執行緒同步現象: 在https://blog.csdn.net/weixin_41827162/article/details/84104421執行緒非同步中, 將方法1中: 建多個執行緒,同時執行多個執行緒,由新到舊逐個釋放執行緒 改成: 建立一個執行緒,
【python3】多執行緒-執行緒非同步(推薦使用)
- python3有threading和_thread兩種執行緒寫法,推薦使用threading。 開多執行緒就是為了使用多執行緒的非同步能力來同時執行多個執行緒。 1. threading方法 #!/usr/bin/python3 # 執行緒非同步 import thread
Java:多執行緒基礎
Java中的多執行緒 程序:一個程式的執行 執行緒:程式中某個順序的流程控制,通俗來講,就是不同的任務 一個程序可以有多個執行緒 執行緒的分類 普通執行緒(非Daemon執行緒) 在Java中,如果還有非Daemon執行緒,整個程式就不會結束 Daemon
【 分類 】- 多執行緒
專欄達人 授予成功建立個人部落格專欄
【muduo】多執行緒伺服器的適用場合與程式設計模型
文章目錄 一、程序與執行緒 1、程序的概念 2、關於程序的一個形象比喻(人) 3、執行緒的概念 二、多程序和多執行緒的適用場景 1、需要頻繁建立銷燬的優先用執行緒 2、
Java這些多執行緒基礎知識你會嗎?
0、併發和並行、程序核線程、多程序和多執行緒的區別: (這裡的時間和時刻上的概念同物理上的一樣) 併發:在一段時間內多個任務同時執行,或者說是在一段很短的時間內可以執行多條程式指令,微觀上看起來好像是可以同時執行多個程序,單核處理器就可以做到。 並行:在同一時刻多個任務
【OpenMP】多執行緒計算過程中任務排程問題
對於OpenMP的任務排程主要針對於並行的for迴圈,當每一次迴圈過程中的計算時間複雜度不一致的時候,簡單的給每一個執行緒分配相同次數的迭代,會導致執行緒計算負載不均衡。不僅如此,對於實時計算的計算機,每一個核心的佔用率是不一樣的。針對該問題,OpenMP中給出
【併發】多執行緒程式設計中條件變數和虛假喚醒的討論
轉自:http://blog.csdn.net/puncha/article/details/8493862 From: http://siwind.iteye.com/blog/1469216 From:http://en.wikipedia.org/wiki/S
【Linux】多執行緒無鎖程式設計--原子計數操作:__sync_fetch_and_add等12個操作
最近自己做了一些涉及多執行緒程式設計的專案,其中就涉及到多執行緒間計數操作、共享狀態或者統計相關時間次數,這些都需要在多執行緒之間共享變數和修改變數,如此就需要在多執行緒間對該變數進行互斥操作和訪問。 通常遇到多執行緒互斥的問題,首先想到的就是
【java基礎】多執行緒匿名內部類和lambda建立方式,及多執行緒中的兩個面試題
一、可以用匿名類和lambda兩個種方式建立多執行緒。 1.利用匿名內部類建立多執行緒並開啟。 new Thread() {//建立方式1 public void run() { for(int x=0; x<50; x++) { System.out
java多執行緒基礎總結【四】虛假喚醒
我們先來看一組例子package com.buerc.thread; public class TesProducerAndConsumer { public static void main(String[] args) { Clerk clerk=new Cler
【對線面試官】Java多執行緒基礎
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c3ad3d76a4d04a9680160f319c889287~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos