關於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);
System.out.println(Thread.currentThread().getName()+":"+"運行方法main"+t.b);
}
}
結果:
main:運行方法b
main:B2000
Thread-0:B值修改爲1000
Thread-0:運行方法A
main:運行方法main1000