1. 程式人生 > >java學習筆記(第11天)

java學習筆記(第11天)

成員變數和區域性變數的區別:

 

  1. 作用域不同:區域性變數的作用域僅限於定義它的方法;成員變數的作用域在這個類內部都是可見的;
  2. 初始值不同:java會給成員變數一個初始值,java不會給區域性變數賦予初始值;
  3. 在同一個方法中,不允許有同名區域性變數;在不同的方法中,可以有同名區域性變數;
  4. 兩類變數同名時,區域性變數具有更高的優先順序。

構造方法:

 

  1. 使用new+構造方法 建立一個新的物件
  2. 構造方法是定義在Java類中的一個用來初始化物件的方法,構造方法與類同名且沒有返回值
  3. 當沒有指定構造方法時,系統會自動新增無參的構造方法
  4. 當有指定構造方法,無論是有參、無參的構造方法都不會自動新增無參的構造方法
  5. 構造方法的過載:方法名相同,但引數不同的多個方法,呼叫時自動根據不同的引數選擇相應的方法
  6. 構造方法不但可以給物件的屬性賦值,還可以保證給物件的屬性賦一個合理的值

測量上下文切換次數和時長:

 

  1. 使用Lmbench3可以測量上下文切換的時長
  2. 使用vmstat可以測量上下文 切換的次數

如何減少上下文切換

 

  1. 減少上下文切換的方法有無鎖併發程式設計、CAS演算法、使用最少執行緒和使用協程。(協程:在單執行緒裡實現多工的排程,並在單執行緒裡維持多個任務間的切換。)
  2. 避免死鎖的幾個常見方法:
      • 避免一個執行緒同時獲取多個鎖。
      • 避免一個執行緒在鎖內同時佔用多個資源,儘量避免每個鎖只佔用一個資源。
      • 嘗試使用定時鎖,使用lock.tryLock(timeout)來替代使用內部鎖機制。
      • 對於資料庫鎖,加鎖和解鎖必須在一個數據庫連線裡,否則會出現解鎖失敗的情況。

資源限制的挑戰:

 

  1. 什麼是資源限制?資源限制是指在進行併發程式設計時,程式的執行速度受限於計算機硬體資源或軟體資源。硬體資源限制有頻寬的上傳/下載速度、硬碟讀寫速度和CPU的處理速度。軟體資源限制有資料庫的連線數和socket連線數等。
  2. 資源限制引發的問題:增加了上下文切換和資源排程的時間。
  3. 如何解決資源限制的問題?對於硬體資源限制,使用叢集併發執行程式,對於軟體資源限制,考慮使用資源池將資源複用。
  4. 在資源限制情況下進行併發程式設計?根據不同的資源限制調整程式的併發度。

在多執行緒併發程式設計中synchronized和volatile都扮演著重要的角色。volatile是輕量級的synchronized,它在多處理器開發中保證了共享變數的“可見性”。可見性的意思是當一個執行緒修改一個共享變數時,另外一個執行緒能讀到這個修改的值。如何volatile變數的修飾符使用恰當的話,它比synchronized的使用和執行成本更低,因為它不會引起執行緒上下文的切換和排程。

volatile的兩條實現原則:1)Lock字首指令會引起處理器快取回寫到記憶體。2)一個處理器的快取回寫到記憶體會導致其他處理器的快取無效。

在使用volatile變數時,用一種追加位元組的方式來優化隊列出隊和入隊的效能。

synchronized實現同步的基礎:Java中的每一個物件都可以作為鎖,具體表現為以下三種形式:

 

  1. 對於普通同步方法,鎖是當前例項物件。
  2. 對於靜態同步方法,鎖是當前類的Class物件
  3. 對於同步方法塊,鎖是Synchonized括號裡配置的物件。

當一個執行緒試圖訪問同步程式碼塊,它首先必須得到鎖、退出或丟擲異常時必須釋放鎖,JVM基於進入和退出Moniter物件來實現方法同步和程式碼塊同步,但兩者的實現細節不一樣。程式碼塊同步是使用monitorenter和monitorexit指令實現的,而方法同步是使用另外一種方式實現的。monitorenter指令是在編譯後插入到同步程式碼塊的開始位置,而monitorexit是插入到方法結束處和異常處,JVM要保證monitorenter必須由對應的monitorexit與之匹配。任何物件都有一個monitor與之關聯,當且一個monitor被持有後,它將處於鎖定狀態。執行緒執行到monitorenter指令時,將會嘗試獲取物件所對應的monitor的所有權,即嘗試獲取物件的鎖。

synchronize用的鎖是存在java物件頭裡的。在執行期間,Mark Word裡儲存的資料會隨著鎖標誌位的變化而變化。

鎖可以升級但不能降級,意味著偏向鎖升級成輕量級鎖後不能降級成偏向鎖。目的是提高獲得鎖和釋放鎖的效率。

在大多數情況下,鎖不均不存在多執行緒競爭,而且總是由同一執行緒多次獲得,為了讓執行緒獲得鎖的代價更低而引入了偏向鎖。當一個執行緒訪問同步塊並獲取鎖時,會在物件頭和棧幀中的鎖記錄裡儲存鎖偏向的執行緒ID,以後該執行緒在進入和退出同步塊時不需要進行CAS操作來加鎖和解鎖,只需簡單地測試一下物件頭的Mark Word裡是否儲存著指向當前執行緒的偏向鎖。如果測試成功,表示執行緒已經獲得了鎖,如果測試失敗,則需要再測試一下Mark Word中偏向鎖的標識是否設定為1(表示當前是偏向鎖);如果沒有設定,則使用CAS競爭鎖,如果設定了,則嘗試使用CAS將物件頭的偏向鎖指向當前執行緒。

(1)偏向鎖的撤銷,偏向鎖使用了一種等到競爭出現才釋放鎖的機制,所以當其他執行緒嘗試競爭偏向鎖時持有偏向鎖的現場才會釋放鎖。

(2)程式預設會進入輕量級鎖狀態。