synchronized void setA() throws Exception{ Thread.sleep(1000); setB(); } synchronized void setB() throws Exception{ Thread.sleep(1000); }
區別java
static synchronized方法是類鎖,synchronized方法是對象鎖算法
synchronized至關於 this.synchronized,static synchronized至關於Something.synchronized編程
pulbic class Test(){ public synchronized void A(){} public synchronized void B(){} public static synchronized void cA(){} public static synchronized void cB(){} }
新建兩個實例,x和y數組
1 x.A()與x.B() 2 x.A()與y.A() 3 x.cA()與y.cB() 4 x.A()與Test.cA()
四種狀況哪組方法何以被多個以上線程同時訪問?併發
Lock是一個接口函數
public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(); boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition(); }
lock()
、tryLock()
、tryLock(long time, TimeUnit unit)
和lockInterruptibly()
是用來獲取鎖的。unLock()
方法是用來釋放鎖的。lock()
日常使用得最多的一個方法,就是用來獲取鎖。若是鎖已被其餘線程獲取,則進行等待。性能
使用Lock必須在try{}catch{}
塊中進行,而且將釋放鎖的操做放在finally
塊中進行,以保證鎖必定被被釋放,防止死鎖的發生。this
Lock lock = ...; lock.lock(); try{ //處理任務 }catch(Exception ex){ }finally{ lock.unlock(); //釋放鎖 }
tryLock()
tryLock()
有返回值的,它表示用來嘗試獲取鎖,若是獲取成功,則返回true,若是鎖已被其餘線程獲取,則返回false。線程
這個方法會當即返回,在拿不到鎖時也不會一直在那等待。設計
Lock lock = ...; if(lock.tryLock()) { try{ //處理任務 }catch(Exception ex){ }finally{ lock.unlock(); //釋放鎖 } }else { //若是不能獲取鎖,則直接作其餘事情 }
tryLock(long time, TimeUnit unit)
此方法在拿不到鎖時會等待必定的時間,在時間期限以內若是還拿不到鎖,就返回false。若是若是一開始拿到鎖或者在等待期間內拿到了鎖,則返回true。
lockInterruptibly()
方法比較特殊,當經過這個方法去獲取鎖時,若是線程正在等待獲取鎖,則這個線程可以響應中斷,即中斷線程的等待狀態。也就使說,當兩個線程同時經過lock.lockInterruptibly()
想獲取某個鎖時,倘若此時線程A獲取到了鎖,而線程B還在等待,那麼對線程B調用threadB.interrupt()方法中斷線程B的等待過程。
lockInterruptibly()
當經過lockInterruptibly()方法獲取某個鎖時,若是不能獲取到,只有進行等待的狀況下,是能夠響應中斷的。
而用synchronized修飾的話,當一個線程處於等待某個鎖的狀態,是沒法被中斷的,只有一直等待下去。
當一個線程獲取了鎖以後,是不會被interrupt()方法中斷的。單獨調用interrupt()方法不能中斷正在運行過程當中的線程,只能中斷阻塞過程當中的線程。
lockInterruptibly()
的聲明中拋出了異常,因此lock.lockInterruptibly()
必須放在try塊中或者在調用lockInterruptibly()
的方法外聲明拋出InterruptedException。
public void method() throws InterruptedException { lock.lockInterruptibly(); try { //..... } finally { lock.unlock(); } }