① java線程的顯式同步監視器和隱式同步監視器以什麼做區分的
隱式(Synchronized)鎖和顯式(java.util.Lock)鎖
為了控制多個線程按照正確的順序來訪問共享數據,Java提供了提供了兩種鎖方案
1.隱式鎖(Synchronized)
這一種就是比較大家熟悉的synchronized關鍵字,因為Java中每個對象都實現了lock的功能,所以synchronized正是利用了這一特性,來控制並發訪問.使用synchronized關鍵字可以保證使用同一個鎖的方法或代碼塊在不同的線程里執行時是原子的即不可分割的(Atomic),這是通過阻塞(blocking)的方式來實現原子性,後面的文章會提到非阻塞(non-blocking)的方式實現原子操作.
public synchronized void safeMethod() {
} //Lock是該方法所屬的對象
public static void safeMethod(){
} //Lock是該類的class對象
synchronized(xxxObject){
} //Lock是xxxObject
這種方法因為不能顯式的對Lock對象進行各種操作,所以有很多不便性,JDK1.5引入了顯式鎖
2.顯式鎖
可以查看 java.util.,concurrent.Lock 介面,實現該介面的類提供了顯式鎖的功能,我們看看Lock介面
void lock(); //嘗試獲取鎖,若得不到著等待(不可中斷,類似於synchronized方式)
void lockInterruptibly() ; //可中斷的嘗試獲取鎖
boolean tryLock();嘗試獲取鎖,不管得到與否立即返回
boolean tryLock(long time, TimeUnit unit)嘗試獲取鎖,若得不到等到一段時間
void unlock();// 釋放鎖
Condition newCondition();//創建於該鎖相關的條件變數,實現精確等待/喚醒
3.兩者區別與聯系
顯式和隱式鎖都能實現對共享資源的控制,兩者在內存同步上是同樣的機制,但是顯式鎖提供了更靈活更強大的介面
1.synchronized 對多個鎖只能按照獲得鎖的順序的反序釋放(先獲得後釋放),顯式鎖可以
按照需要釋放鎖,無此約束.
2.顯式鎖提供可中斷的獲取鎖的方法,lockInterruptibly
3.顯式提供嘗試獲得鎖方法
4.提供精度更細的等待與喚醒(利用Condition)
特別注意顯式鎖的 xx.lock()方法只是獲取了xx對象表達的鎖,並不是獲取了xx內置的隱式鎖,這個要注意區分,與synchronized(xx)是兩回事
② Java 線程同步幾種方式
(1)同步來方法:
即有synchronized關鍵字修飾的自方法。 由於java的每個對象都有一個內置鎖,當用此關鍵字修飾方法時,內置鎖會保護整個方法。在調用該方法前,需要獲得內置鎖,否則就處於阻塞狀態。
(2)同步代碼塊
即有synchronized關鍵字修飾的語句塊。被該關鍵字修飾的語句塊會自動被加上內置鎖,從而實現同步
(3)使用特殊域變數(Volatile)實現線程同步
a.volatile關鍵字為域變數的訪問提供了一種免鎖機制
b.使用volatile修飾域相當於告訴虛擬機該域可能會被其他線程更新
c.因此每次使用該域就要重新計算,而不是使用寄存器中的值
d.volatile不會提供任何原子操作,它也不能用來修飾final類型的變數
(4)使用重入鎖實現線程同步
在JavaSE5.0中新增了一個java.util.concurrent包來支持同步。ReentrantLock類是可重入、互斥、實現了Lock介面的鎖, 它與使用synchronized方法和快具有相同的基本行為和語義,並且擴展了其能力。
(5)使用局部變數實現線程同步
③ 告訴你什麼是java多線程定義及線程安全
網頁鏈接
舉個簡單易懂的例子,多線程相當於一條馬路上的多條車道,單車道行駛車輛速度較慢,且可能產生擁堵,多車道可緩解車速、擁堵情況。
線程是指進程中的一個執行流程,一個進程中可以運行1-n個線程。也可以說是在同一個進程內又可以執行多個任務,而每一個任務我們就可以看成是一個線程。
是程序的執行單元,執行路徑。是程序使用CPU的最基本的單位
如果程序只有一條執行路徑,那麼該程序就是單線程程序
如果程序有多條執行路徑,那麼該程序就是多線程程序
2、多線程的意義:
多線程不是為了提高程序的執行速度,而是為了提高程序的使用率。
多線程的執行都是為了搶佔CPU的使用率。
不能保證多線程程序會在什麼時候優先搶到使用權,所以線程的執行具有隨機性
3、多線程的優點:
充分利用硬體資源。由於線程是cpu的基本調度單位,所以如果是單線程,那麼最多隻能同時在一個處理器上運行,意味著其他的CPU資源都將被浪費。而多線程可以同時在多個處理器上運行,只要各個線程間的通信設計正確,那麼多線程將能充分利用處理器的資源。
多線程程序能將代碼量巨大,復雜的程序分成一個個簡單的功能模塊,每塊實現復雜程序的一部分單一功能,這將會使得程序的建模,測試更加方便,結構更加清晰,更加優雅
為了避免阻塞,單線程應用程序必須使用非阻塞I/O,這樣的I/O復雜性遠遠高於同步I/O,並且容易出錯。
4、多線程的缺點:
線程安全:由於統一進程下的多個線程是共享同樣的地址空間和數據的,又由於線程執行順序的不可預知性,一個線程可能會修改其他線程正在使用的變數,這一方面是給數據共享帶來了便利;另一方面,如果處理不當,會產生臟讀,幻讀等問題,好在Java提供了一系列的同步機制來幫助解決這一問題,例如內置鎖。
④ java多線程有幾種實現方法線程之間如何同步
Java多線程有兩種實現方式:一種是繼承Thread類,另一種是實現Runable介面,大同小異,推薦後者,因為實現介面的話這個類還可以實現別的介面和繼承一個類,靈活性好,若繼承Thread類之後,就無法繼承其他類了。
至於實現同步,最簡單的方法就是使用同步塊,synchronized(){語句塊}
當多個線程同時訪問到同步語句塊時,會由一個線程先獲得對象鎖,獲取對象鎖的線程執行完畢之後,釋放鎖,其他線程再次競爭鎖,一個一個通過,不存在兩個以上線程同時執行同步語句塊的情況。
⑤ java.關於線程同步的幾個知識點
擴展:
為何要使用同步?
因為java允許多線程並發控制,當多個線程同時回操作一個可共享的資源變答量時(如數據的增刪改查),所以將會導致數據不準確,相互之間產生沖突,因此加入同步鎖以避免在該線程沒有完成操作之前,被其他線程的調用,從而保證了該變數的唯一性和准確性。
2.同步方法
有synchronized關鍵字修飾的方法。
由於java的每個對象都有一個內置鎖,當用此關鍵字修飾方法時,內置鎖會保護整個方法。在調用該方法前,需要獲得內置鎖,否則就處於阻塞狀態。
列:
public synchronized void save(){}
3.同步代碼塊
有synchronized關鍵字修飾的語句塊。
被該關鍵字修飾的語句塊會自動被加上內置鎖,從而實現同步
列: synchronized(object){ }
4.用特殊域變數(volatile)實現線程同步
5.用重入鎖實現線程同步
6.用局部變數實現線程同步