1. 程式人生 > >JAVA基礎22-多執行緒(一)【多執行緒的概念,執行緒狀態及其轉換】

JAVA基礎22-多執行緒(一)【多執行緒的概念,執行緒狀態及其轉換】

多執行緒

一.概念

         1. 程序:程序是表示資源分配的的基本概念,又是排程執行的基本單位,是系統中的併發執行的單位。

          2. 執行緒:單個程序中執行中每個任務就是一個執行緒。執行緒是程序中執行運算的最小單位。且執行緒只能屬於一個執行緒。

         3.執行緒是一種輕量級的程序。

        4.執行緒沒有地址空間,執行緒包含在程序的地址空間中。

         5.多執行緒三大特性: 原子性,可見性,有序性。

二. Java執行緒具有的5種狀態

       新建狀態(NEW):當執行緒物件被建立後,即進入新建狀態。【Thread t=new Thread()】

       就緒狀態(Runable):當執行緒物件呼叫了start方法,即進入就緒狀態,等待cpu排程執行【t.start()】

       執行狀態(Running) :就緒狀態的執行緒,被cpu排程即,進入執行狀態

       阻塞狀態(Blocked):處於執行狀態中的執行緒由於某種原因,暫時放棄對CPU的使用權,停止執行,此時執行緒進入阻塞狀態;

             三種阻塞狀態

                 A.等待阻塞;執行狀態中執行緒執行了wait()方法,使得本執行緒進入阻塞狀態

                 B.同步阻塞;執行緒在獲取synchronized同步鎖(鎖被其他執行緒鎖佔有),進入同步阻塞狀態

                 C.其他阻塞:執行緒呼叫了sleep(),join()或者發出I/O請求時,執行緒會進入阻塞狀態,當sleep超時,join等待執行緒終止或者超時,I/O請求完成,執行緒會進入就緒狀態

       死亡狀態(Dead): 執行緒執行完了,或者因異常退出run()方法。

三.執行緒屬性

     1.執行緒優先順序

             執行緒範圍:0-10;預設優先順序為5;高優先順序的執行緒先執行。

             預設情況下,執行緒是繼承父類的優先順序;也可通過setPriority()修改優先順序。

     2.使用者執行緒和守護執行緒

         使用者執行緒:非守護執行緒,常規的執行緒

         守護執行緒:作用是為其他執行緒提供服務。只要當JVM還有使用者執行緒,那麼守護執行緒就會一直工作下去。例如:垃圾回收期;

         程式編寫者可以設定守護執行緒;方法: t.setDaemon(true)

四.執行緒建立(NEW和Runable狀態)

       1.繼承Thread類,重寫run()方法

package com.demo9aa.demo7;

public class ThreadA extends Thread {
@Override
public void run() {
	// TODO Auto-generated method stub
	super.run();
	int i =0;
	for(;i<10;i++){
		System.out.println(i);
	}
	
}

public static void main(String[] args) {
	ThreadA a=new ThreadA();//建立ThreadA;new狀態
	a.start();//runable狀態
}
}

       2.實現Runable介面,並重寫該介面的run()方法

package com.demo9aa.demo7;

public class ThreadB implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		int i=0;
		for(;i<10;i++){
			System.out.println(i);
		}
	}

}

       3.使用Callable和Future介面建立執行緒。

            A.建立Callable介面的實現類,並實現call()方法。

            B.使用FutureTask類來包裝Callable實現類的物件,

            C.此FutureTask物件作為Thread物件的target來建立執行緒。

package com.demo9aa.demo7;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

public class Demo1 {
	public static void main(String[] args) {
		//A
		Callable<Integer> c=new CallAbleA();
		//B
		FutureTask<Integer> f=new FutureTask<>(c);
		//C
		Thread r=new Thread(f);
		r.start();
	}

	
}
class CallAbleA implements Callable<Integer>{
 int i=0;
	@Override
	public Integer call() throws Exception {
		// TODO Auto-generated method stub
		for(;i<10;i++){
			System.out.println(i);
		}
		return i;
	}
	
	
} 

  五.執行緒讓步(yield方法)

      從執行態轉換為就緒態有兩種情況  1.時間片用完。2.執行緒主動呼叫yield()

        yield方法作用:主動歸還資源,使自己在就緒態

  六.其他阻塞(I/O請求,sleep,join)

       I/O請求:當執行緒開始進行I/O操作時,執行緒進入阻塞狀態。I/O操作完成後,執行緒進入就緒態 

       join函式: 讓一個執行緒等待另一個執行緒完成,才可以繼續執行【在子執行緒未完成或者未超時之間,父執行緒進入阻塞狀態;子執行緒完成或者超時,父執行緒進入就緒態】

       sleep函式:讓當前正在執行的執行緒,暫停製定時間,並進入阻塞狀態【在睡眠時間,執行緒進入阻塞狀態,超時後,恢復到就緒態】

七.等待阻塞和同步阻塞

   A:等待阻塞 

    當正在執行時的執行緒(已獲得鎖),呼叫wait()方法時,執行緒主動放棄鎖,此時執行緒進入 等待阻塞狀態。

    B: 同步阻塞

      當正在執行的執行緒(未獲得鎖),獲得鎖失敗(鎖被其他執行緒鎖佔用),執行緒進入同步阻塞階段。

      當執行執行緒,呼叫notify和notifyAll方法;此時喚醒“等待阻塞的執行緒“進入同步阻塞階段。

      同步阻塞的執行緒,一旦獲得鎖,就進入就緒態。

   八.執行緒中斷

    8-1.歷史方法:  Thread有成員方法:suspend和stop都用於中斷執行緒。 問題? ?? 執行緒強制中斷,會導致鎖永遠無法歸還。

    8-2.最新做法:  使用等待/通知或者給哪個執行緒一箇中斷訊號,讓他自己決定中斷。

           8-2-1.涉及方法:             

                 interrupted()方法:  靜態方法;檢視當前中斷訊號,並其清除中斷訊號

                 isInterrupted()方法: 檢視當前中斷訊號。

                 interrupt()方法:修改被呼叫執行緒的中斷狀態,告知那個執行緒,他需要被中斷。

           8-2-2.詳細操作如下:

              對於非阻塞執行緒:修改了中斷狀態【Thread.isInterrupted返回true】,無任何特殊現象

              對於可取消的阻塞狀態的執行緒中:(wait,sleep,join)

                    A  執行緒收到中斷訊號後,會丟擲InterruptedException;

                    B  丟擲異常後會把中斷狀態置為true

              對於不可中斷阻塞的執行緒中:(I/O請求時):

                   執行緒收到中斷資訊後,,他們不會丟擲InterruptedException,且不會因為中斷情況,而退出阻塞。

            注意:

                    嘗試獲取一個內部鎖的操作(進入一個 synchronized 塊)是不能被中斷的;                     但是 ReentrantLock 支援可中斷的獲取模式即 tryLock(long time, TimeUnit unit)。