synchronized的參數的理解
- 昨天天問一號發射成功,然後今天輸入法成爲了火星文,沒辦法
- 我之前一直不知道這個參數有什麽用,現在才大致明白一點。以下個人理解,有錯誤請指出
- 這個對象就像現實中的鎖,而那些同步代碼塊和同步方法就像是厠所,綫程就像是人。被synchronized修飾之後,就像是人進去上厠所,拿著鎖把這個厠所鎖上防止其他人在進去,等自己解決完了,再鎖釋放。
- 因此這就出現一個問題,一個人拿著這把鎖去鎖了一個厠所,那麽還能不能拿著這把鎖去鎖其他的厠所(代碼塊或方法)。按道理來説是不能的,因此有如下測試代碼:
問題一:綫程使用該對象已經上鎖,那麽還能否使用該對象在鎖其他的代碼塊和方法
public class SynchronizedTest {
public void say() {
synchronized(this) {
int i = 0;
while(i < 20) {
System.out.println("正在説話"+i);
i++;
}
}
}
public void run() {
synchronized(this) {
int i = 0;
while(i < 20) {
System.out.println("正在跑步"+i);
i++;
}
}
}
}
public class Test {
public static void main(String[] args) {
SynchronizedTest s = new SynchronizedTest();
new Thread(s::say).start();
new Thread(s::run).start();
}
}
-
運行結果
-
根據結果我們可以知道,理論上多綫程是交替執行,但是這裏是先執行完say方法,在執行run方法。因爲它們使用的是同一對象,就像是同一把鎖,同時只能鎖一個地方,只有一個地方釋放鎖了才能鎖下一個地方。
-
我使用不同對象來執行看看
-
從結果可以知道不同的對象沒有影影響
問題二:多個綫程同時對一個對象的同一方法進行操作時,一次只能一個綫程執行
public class SynchronizedTest2 implements Runnable {
private int i = 0;
public synchronized void add() {
i++;
System.out.println(Thread.currentThread().getName() + "===" + i);
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
add();
}
}
public static void main(String[] args) {
SynchronizedTest2 s = new SynchronizedTest2();
new Thread(s, "一號").start();
new Thread(s, "二號").start();
}
}
- 去掉synchronized,這裏明顯的指導兩個綫程同時進入該方法