[仁潤雲技術團隊]併發程式設計-(1)基本概念

仁潤雲發表於2018-10-15

程式:一個正在執行程式的例項,包括程式計數器,暫存器以及變數的當前值。在作業系統中,每一個程式都有其地址空間和控制執行緒。

地址空間:要保證多個應用程式同時處於記憶體中並且不互相影響,則需要解決兩個問題:保護和重定位。目前的辦法是創造一個新的記憶體抽象:地址空間。就像程式的概念創造了一類抽象的CPU以執行程式一樣,地址空間為程式創造了一種抽象的記憶體。地址空間是一個程式可用於定址記憶體的一套地址集合。每個程式都有一個自己的地址空間,並且這個地址空間獨立於其他程式的地址空間。

執行緒:存在同一個地址空間存在多個控制執行緒的情況。執行緒是作業系統能夠進行運算排程的最小單位,是程式中的實際運作單位。一個執行緒指的是程式中一個單一順序的控制流。

在Unix System V及SunOS中也被稱為輕量程式(lightweight processes),但輕量程式更多指核心執行緒(kernel thread),而把使用者執行緒(user thread)稱為執行緒。

同一程式中的多條執行緒將共享該程式中的全部系統資源,如虛擬地址空間,檔案描述符和訊號處理等等。但同一程式中的多個執行緒有各自的呼叫棧(call stack),自己的暫存器環境(register context),自己的執行緒本地儲存(thread-local storage)。

多執行緒的好處 在多核或多CPU,或支援Hyper-threading的CPU上使用多執行緒程式設計的好處是顯而易見,即提高了程式的執行吞吐率。在單CPU單核的計算機上,使用多執行緒技術,也可以把程式中負責I/O處理、人機互動而常被阻塞的部分與密集計算的部分分開來執行,編寫專門的workhorse執行緒執行密集計算,從而提高了程式的執行效率。

runnable:封裝了程式碼執行序列的執行緒物件。

建立Runnable:實現Runnable介面的匿名類/lambda表示式。

建立執行緒:將Rannable物件作為Thread類的建構函式引數。直接繼承Thread類,並重寫run()。

// 通過Runnable傳遞到Thread類中
Runnable r = new Runnable() {
	@Override
	public void run() {
		// work
	}
}
Thread t = new Thread(r);

// 直接繼承Thread類
Class MyThread extends Thread {
	@Override
	public void run() {
		// work
	}
}
MyThread t = new MyThread();
複製程式碼

執行緒的5個特徵:執行緒名稱,存活標識,執行狀態,優先順序以及是否為守護程式。

執行緒的執行狀態:NEW,RUNNABLE,BLOCKED,WAITTING,TIME_WAITTING,TERMINATED。

一些基本操作

執行緒的中斷:interrupt(),interrupted(),isInterrupted()。

等待執行緒:join()方法,當一個執行緒啟動另一個執行緒時,被啟動的執行緒非常耗時,主執行緒呼叫join()方法,主執行緒會等待該執行緒完成工作再處理其結果。

class ThreadJoining extends Thread {
  @Override
  public void run() {
    for (int i = 0; i < 2; i++) {
      try {
        Thread.sleep(500);
        System.out.println("C Current Thread: "
                + Thread.currentThread().getName());
      } catch (Exception ex) {
        System.out.println("Exception has" +
                " been caught" + ex);
      }
      System.out.println(i);
    }
  }
}

public class GFG {
  public static void main(String[] args) {

    // creating two threads
    ThreadJoining t1 = new ThreadJoining();
    ThreadJoining t2 = new ThreadJoining();
    ThreadJoining t3 = new ThreadJoining();

    // thread t1 starts
    t1.start();

    // starts second thread after when
    // first thread t1 is died.
    try {
      System.out.println("A Current Thread: "
              + Thread.currentThread().getName());
      t1.join();
    } catch (Exception ex) {
      System.out.println("Exception has " +
              "been caught" + ex);
    }

    // t2 starts
    t2.start();

    // starts t3 after when thread t2 is died.
    try {
      System.out.println("B Current Thread: "
              + Thread.currentThread().getName());
      t2.join();
    } catch (Exception ex) {
      System.out.println("Exception has been" +
              " caught" + ex);
    }
    t3.start();
  }
}
複製程式碼

result:

A Current Thread: main
C Current Thread: Thread-0
0
C Current Thread: Thread-0
1
B Current Thread: main
C Current Thread: Thread-1
0
C Current Thread: Thread-1
1
C Current Thread: Thread-2
0
C Current Thread: Thread-2
1
複製程式碼

在這個例子裡是主執行緒等待被啟動執行緒完成工作(死亡)才會處理接下來的工作。

執行緒睡眠:Thread.sleep() 暫時性停止執行。

歡迎關注:www.renrunyun.com

相關文章