Java—進程與線程

  • 進程與線程

  進程是程序(任務)的執行過程,具備動態性;持有資源(共享內存、共享文件)和線程,是資源和線程的載體。java

  線程是系統中最小的執行單元,同一進程中有多個線程,線程共享進程的資源。數據庫

  線程的交互,交互的方式包括互斥與同步。編程

  •  線程的經常使用方法

  java對線程的支持主要體如今類Thread和接口Runnable,它們都繼承java.lang包,有一個共同的方法run()安全

   

  • 線程中止錯誤的方法:stop()、interrupt()
  • 線程中止的正確方法
public class ArmyRunnable implements Runnable {
    //volatile保證了線程能夠正確讀取其餘線程寫入的值
    volatile boolean keepRunning = true;
    @Override
    public void run() {
        while(keepRunning) {
            //發動五連擊
            for (int i = 0; i < 5 ; i++) {
                System.out.println(Thread.currentThread().getName() + "進攻對方[" + i + "]");
            }
            //暫停
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + "結束了戰鬥");
    }
}
  •  爭用條件

  當多個線程同時共享訪問同一數據(內存區域)時,每一個線程都嘗試操做該數據,從而致使數據被破壞(corrupted),這種現象稱爲爭用條件。網絡

  • 線程的交互:互斥與同步

  互斥:在同一時間,只能有一條線程去對咱們的關鍵數據或臨界區進行操做。多線程

  互斥的實現:sysnchronized(intrinsic lock),sysnchronized至關於給代碼加上一把鎖,使其餘線程不能進入這個關鍵區域訪問咱們的關鍵資源。併發

  同步:是線程之間的一種通訊機制, 因爲一條線程的某些條件不具有,使得其餘線程處於某種等待的狀態,以後因爲條件具有了,一條線程會用某種方式喚醒其餘的線程。ide

  同步的實現:wait()/notify()/notifyAll()--Object對象的成員方法工具

  wait set 是線程的休息室性能

public void transfer(int from, int to, double amount) {
        //經過synchronized 關鍵字來實現互斥,synchronized既能夠出如今方法之上,也能以塊的形式出如今方法體之中
        //經過對lockObj加鎖實現互斥
        //加鎖操做是有開銷的,屢次加鎖操做會下降系統的性能
        synchronized (lockObj) {//while循環,保證條件不知足時任務都會被條件阻擋,而不是繼續競爭CPU資源
            while (energyBoxes[from] < amount) {
                try {
                    //條件不知足,將當前線程放入鎖對象(lockObj)上的wait set
                    //wait set 是線程的休息室
                    lockObj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName());
            energyBoxes[from] -= amount;
            System.out.printf("從%d轉移%10.2f單位能量到%d", from, amount, to);
            energyBoxes[to] += amount;
            System.out.printf("能量總和:%10.2f%n",getTotalEnergies());
            
            //喚醒全部在lockObj對象上等待的線程
            lockObj.notifyAll();
        }
        
    }
  • Runnable方式和Thread方式建立線程的區別

 

  1. Runnable方式能夠避免Thread方式因爲Java單繼承特性帶來的缺陷
  2. Runnable的代碼能夠被多個線程(Thread實例)共享,適合於多個線程處理同一資源的狀況
  • 線程的生命週期

  

  1. 就緒:建立了線程對象後,調用了線程的start()方法(此時線程只是進入了線程隊列,等待獲取CPU服務,具有了運行的條件,但並不必定已經開始運行了)。
  2. 運行:處於就緒狀態的線程,一旦獲取了CPU資源,便進入到運行狀態,開始執行run()方法裏面的邏輯。
  3. 終止:線程的run()方法執行完畢,或者線程調用了stop()方法(這種方法已經out),線程便進入終止狀態。
  4. 阻塞:一個正在執行的線程在某些狀況下,因爲某種緣由而暫時讓出了CPU資源,暫停了本身的執行,便進入了阻塞狀態,如調用了sleep()方法
  • 用戶線程和守護線程
  1. 用戶線程:運行在前臺,執行具體的任務,如程序的主線程、鏈接網絡的子線程
  2. 守護線程:運行在後臺,爲其餘前臺線程服務,一旦全部用戶線程都結束運行,守護線程會隨JVM一塊兒結束工做。
  3. 守護線程的應用:數據庫鏈接池中的監測線程、JVM虛擬機啓動後的監測線程。最多見的守護線程是垃圾回收線程
  4. 設置守護線程:經過調用Thread類的setDaemon(true)方法來設置當前的線程爲守護線程。注意:setDaemon(true)必須在start()方法以前調用,不然會拋出異常;在守護線程中產生的新線程也是守護線程;不是全部的任務均可以分配給守護線程來執行,好比讀寫操做或者計算邏輯。
  • 擴展

  Java Memory Mode

  Locks & Condition

  線程安全性: 原子性與可見性 ...

  多線程編程經常使用的交互模型

  Java5中併發編程工具

  • 參考書

  core java

  Java concurrency in practice

相關文章
相關標籤/搜索