天天看點

大資料之多線程學習筆記

  預設情況下,主線程和垃圾回收線程都是由系統建立的,但是我們需要完成自己的功能----建立自己的線程對象。

  • java将線程面向對象了,形成的類就是Thread,在Thread類内部執行任務的方法叫run()
  • 注意:如果想讓run作為任務區,必須讓他去被自動調用.我們通過執行start()方法,來開啟線程,繼而實作run方法的自動調用.

直接使用Thread建立線程對象

// //分析:由于我們實作的實際功能Thread類是決定不了的,是以沒有辦法将我們的功能放入Thread的run方法裡

// //是以Thread的run 方法是一個空方法.如果我們想實作自己的功能,可以寫Thread類的子類,重寫run方法

當我們手動調用run的時候,他失去了任務區的功能,變成了一個普通的方法.

//當run作為一個普通方法時,内部對應的線程跟調用他的位置保持一緻.
           

鎖的條件:

​ * 1.鎖必須是對象 普通的對象/this/位元組碼檔案

* 2.要被所有的線程共享
         * 
         * 注意:位元組碼檔案的使用範圍太大,一般不建議使用.
           

空喚醒

Lock鎖

使用步驟

​ 1.建立ReentrantLock lock = new ReentrantLock();對象,需要注意的是多個線程必須使用同一個

​ 2.把之前的synchronized(鎖){ 用lock.lock()替換

​ 3.把} 用lock.unlock();替換

好處

​ 1.不要考慮鎖對象

​ 2.代碼看起來更加簡潔了

​ 3.可以使用try..catch..finaly把lock.unlock放到finaly中,好處是如果該線程發生了異常,照樣可以釋放鎖

比較synchronized和Lock

  • 1.synchronized:從jdk1.0就開始使用的同步方法-稱為隐式同步
    • synchronized(鎖對象)
    • {//擷取鎖 我們将鎖還可以稱為鎖旗艦或者監聽器
      同步的代碼}//釋放鎖
                 
  • 2.Lock:從jdk1.5開始使用的同步方法-稱為顯示同步
  • 原理:Lock本身是接口,要通過他的子類建立對象幹活兒
  • 使用過程:
  • 首先調用lock()方法擷取鎖
  • 進行同步的代碼塊兒
  • 使用unlock()方法釋放鎖
  • 使用的場景:
  • 當進行多生産者多消費者的功能時,使用Lock,其他的都使用synchronized
  • 使用效率上:Lock高于synchronized

多線程的單例

//餓漢式,由于公共方法中隻有一行公共的代碼,是以不會産生線程安全問題

class SingleInstance1{

private static final SingleInstance1 s = new SingleInstance1();
private SingleInstance1() {
}
public static SingleInstance1 getInstance() {
    return s;
}           

}

//懶漢式,

class SingleInstance2{

private static  SingleInstance2 s = null;
private SingleInstance2() {
}
public  static SingleInstance2 getInstance() {
    if (s == null) {//盡量減少線程安全代碼的判斷次數,提高效率
        

        synchronized (SingleInstance2.class) {//使用同步代碼塊兒實作了線程安全
            if (s == null) {
                s = new  SingleInstance2();
            }
        }
    }
    return s;
}
           

線程停止

​ 1.通過一個辨別結束線程

​ 2.調用stop方法---因為有固有的安全問題,是以系統不建議使用.

​ 3.調用interrupt方法----如果目标線程等待很長時間(例如基于一個條件變量),則應使用 interrupt 方法來中斷該等待。

繼續閱讀