Java synchronized 關於…

關於synchronized  這東西就是看對象 目前也是很木亂  還是要多敲 自己REBUG 坑總是會填滿的

-----------------我是分割的小尾巴 啦啦啦啦

下列是方法
public synchronized void methodA(int a, int b);
public synchronized void methodB(int a){
methodA(a, 0);
}
那麼對於順序問題怎麼看呢
要明白兩個問題,1.鎖的對象是誰,2.誰持有了鎖。
假設方法A和B是在同一個類Test中的兩個方法。

Test t=new Test(); 
t.methodB();

這個時候,methodB方法被調用時,因爲加了synchronized ,需要先獲得一個鎖,這個鎖的對象應該是t,也就是當前的這個Test類的實例,而獲得鎖的東西是線程,也就是說當前線程拿到了t的鎖(而不是你說的B方法獲得鎖),這個時候B方法內調用methodA,因爲A也加了synchronized,也需要獲得一個鎖,因爲A和B都是Test類中的方法,所以當前線程要獲得的鎖的對象也是t。由於當前線程在執行B方法時已經持有了t對象的鎖,因此這時候調用methodA是沒有任何影響的,相當於方法A上沒有加synchronized。

另一種情況:假設現在有兩個Test類
Test t1=new Test(); 
Test t2=new Test(); 
t1.methodB();//此時當前線程持有了t1對象的鎖
t2.methodB();//此時當前線程也持有了t2對象的鎖
當前線程持有了兩把鎖,鎖的對象分別是兩個不同的Test類的實例t1和t2,互相沒有影響。

再一種情況:假設在多線程環境下,兩個線程都可以訪問Test t=new Test(); 
此時假設thread1裏調用t.methodB();同時thread2裏調用t.methodB()

這時假設thread1先搶到t對象的鎖,那麼thread2需要等待thread1釋放t對象的鎖纔可以執行B方法。
結果像這樣:
thread1獲得t的鎖--thread1執行methodB--thread1執行methodA--釋放t的鎖---thread2獲得t的鎖--thread2執行methodB--thread2執行methodA--釋放t的鎖。

寫在後面
如果是下面這個樣子

public synchronized void methodA(int a, int b);
public synchronized void methodB(int a){
};

public static void main(String [ ] args){
TT tt =new TT ();
tt.start();
tt.method B(int a);
}// 因爲方法A和方法B鎖定的是同一對象中的方法 爲synchronized 鎖定的是對象而不是方法  那麼當方法b先獲得鎖之後  那麼a就發生阻塞 必須等到方法b執行完畢之後在去執行方法a 因爲方法b爲主線程的調用  會比開啓新線程得到鎖的速度要快  所以要根據情況設定SLEEP的時候來確定需要的線程先得到鎖

附一下代碼
package n1;



public class test11 implements Runnable{
int b =100;
public synchronized void A() throws InterruptedException{
System.out.println(Thread.currentThread().getName()+":"+"B值修改爲1000");

b=1000;

System.out.println(Thread.currentThread().getName()+":"+"運行方法A");

Thread.sleep(5000);
System.out.println(Thread.currentThread().getName()+":"+"A" +b);
}
public synchronized void B() throws InterruptedException {
System.out.println(Thread.currentThread().getName()+":"+"運行方法b");
Thread.sleep(2500);
b=2000;


System.out.println(Thread.currentThread().getName()+":"+"B" +b);

}
public void run() {
try {
A();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
  
public static void main(String[] args) throws InterruptedException {
test11 t =new test11();
Thread i = new Thread(t);
        i.start();    
t.B();
System.out.println(Thread.currentThread().getName()+":"+"運行方法main"+t.b);

}
}

結果:
main:運行方法b
main:B2000
Thread-0:B值修改爲1000
Thread-0:運行方法A
main:運行方法main1000

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章