多線程考點

1. 線程與進程的區別?

  1. 地址空間: 同一進程的線程共享本進程的地址空間,進程是獨立的地址空間。
  2. 資源擁有: 同一進程內的線程共享本進程的資源如內存、I/O、cpu等,可是進程之間的資源是獨立的。
  3. 健壯性: 一個進程崩潰後,在保護模式下不會對其餘進程產生影響,可是一個線程崩潰整個進程都死掉。因此多進程要比多線程健壯。
  4. 性能: 進程切換時,消耗的資源大,效率高。因此涉及到頻繁的切換時,使用線程要好於進程。一樣若是要求同時進行而且又要共享某些變量的併發操做,只能用線程不能用進程
  5. 執行過程: 每一個獨立的進程程有一個程序運行的入口、順序執行序列和程序入口。可是線程不能獨立執行,必須依存在應用程序中,由應用程序提供多個線程執行控制。
  6. 基本區別: 線程是處理器調度的基本單位,可是進程不是。

2. Thread 與 Runnable

  1. 適合多個相同的程序代碼的線程去處理同一個資源
  2. 能夠避免java中的單繼承的限制
  3. 增長程序的健壯性,代碼能夠被多個線程共享,代碼和數據獨立

3. 線程返回值

  1. 主線程等待
  2. Thread的join方法
  3. Callable接口:FutureTask Or 線程池獲取

Callable接口實現:java

import java.util.concurrent.Callable;

public class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception{
        String value="test";
        System.out.println("Ready to work");
        Thread.currentThread().sleep(5000);
        System.out.println("task done");
        return  value;
    }

}
複製代碼
  1. FutureTask:
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class FutureTaskDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<String> task = new FutureTask<String>(new MyCallable());
        new Thread(task).start();
        if(!task.isDone()){
            System.out.println("task has not finished, please wait!");
        }
        System.out.println("task return: " + task.get());

    }
}
複製代碼
  1. 線程池獲取
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ThreadPoolDemo {
    public static void main(String[] args) {
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        Future<String> future = newCachedThreadPool.submit(new MyCallable());
        if(!future.isDone()){
            System.out.println("task has not finished, please wait!");
        }
        try {
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } finally {
            newCachedThreadPool.shutdown();
        }
    }
}
複製代碼

4. Thread的狀態

  1. New
  2. Runnable
  3. Waiting
  4. Timed Waiting
  5. Blocked
  6. Terminated

5. sleep與wait?

  1. sleep不釋放鎖,wait釋放所對象
  2. sleep是Thread的方法,wait是Object方法

6. 鎖池與等待池?

  1. 鎖池: 假設線程A已經擁有某個對象的鎖,因爲B,C要調用這個對象的synchronized方法,B,C對象就會進入鎖池。
  2. 等待池: A線程調用wait()後,A釋放該對象的鎖,A就會進入該對象的等待池。

7. notify與notifyall?

  1. notifyAll會讓全部等待池的線程所有進入鎖池去競爭鎖機會
  2. notify是隨機選取一個

8. yield是暗示cpu釋放

9. interrupt函數

  1. 被拋棄的函數:stop
  2. interrupt是通知線程須要被中斷,若是線程處於被阻塞狀態,那麼線程將拋出InterruptedException異常
  3. 若是線程處於活動狀態,則將標誌位設爲true。被中斷線程將繼續執行,不受影響。

10. 線程狀態之間的轉化

synchronized

對象鎖

  1. 同步代碼塊中的 this
  2. 同步非靜態方法

類鎖

  1. 同步代碼塊 類.class
  2. 同步靜態方法

重入

同一對象進入同一資源多線程

自旋鎖和自適應自旋鎖

  1. 自旋鎖:經過讓線程執行忙循環等待鎖釋放,不讓出cpu(鎖被佔用時長較長則更耗費性能,因此會有自旋次數限制)
  2. 自適應自旋鎖:自選次數很差設定,自適應自旋鎖會根據上次自旋時間決定是否自旋

鎖消除:

對上下文進行檢測,去除不可能存在競爭的鎖併發

鎖粗化

經過加鎖的範圍,減小反覆加鎖與減鎖app

sychronized四種狀態

鎖膨脹的方向;無鎖-->偏向鎖-->輕量級鎖-->重量級鎖ide

  1. 偏向鎖:若是一個線程得到了鎖,那麼鎖進入偏向模式,可省去鎖申請的操做
  2. 輕量級鎖:線程交替執行
  3. 重量級鎖:

鎖的內存語義

  1. 鎖釋放:java內存模型會把該線程對應的本地變量刷新到主內存
  2. 鎖獲取:會將該線程對應的本地內存置爲無效,臨界區必須從主內存讀取共享變量

sycronized 與 ReentryLock的區別

  1. 公平鎖:獲取鎖的順序按照前後調用lock方法順序
  2. 非公平鎖:搶佔順序不必定

happens-before

  1. 程序次序
  2. 鎖定
  3. volatile
  4. 傳遞
  5. 線程啓動
  6. 線程中斷
  7. 線程終結
  8. 對象終結

悲觀鎖 與 樂觀鎖

  1. 悲觀鎖始終假設衝突
  2. 樂觀鎖只在提交數據時檢測(CAS,J.U.C)
相關文章
相關標籤/搜索