[英]Java Synchronization (for specific example)
package sync.block.lock.on.thisObj;
public class Counter {
int count = 0;
public void increment() {
synchronized (this) {
count++; // STATEMENT 1
//System.out.println(count);
}
System.out.println(count+" increment"); // STATEMENT 2
//System.out.println(count);
}
public void decrement() {
synchronized (this) {
count--; // STATEMENT 3
//System.out.println(count);
}
System.out.println(count+" decrement"); // STATEMENT 4
//System.out.println(count);
}
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
counter.decrement();
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
counter.increment();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("Main Thread: "+counter.count);
}
}
結果如下:
0 increment
1 increment
2 increment
3 increment
4 increment
5 increment
6 increment
0 decrement // How this entry and all the following entries?
6 decrement
5 decrement
4 decrement
3 decrement
2 decrement
1 decrement
7 increment
1 increment
2 increment
0 decrement
1 decrement
0 decrement
Main Thread: 0
我同意預期的結果, sysout
應該位於synchronized
塊內。
但是,執行什么順序可能導致產生條目0 decrement
及其所有后續條目?
我期望的執行順序:
STATEMENT 1 - increments 1
STATEMENT 3 - decrements 1
STATEMENT 2 - 0 increment printed
STATEMENT 1
--> possibility for STATEMENT 3 to be executed.But it didn't.Because if it had,next statement would have printed 0.
STATEMENT 2 - 1 increment
STATEMENT 1
--> possibility for STATEMENT 3 to be executed.But it didn't.Because if it had,next statement would have printed 1.
STATEMENT 2 - 2 increment
STATEMENT 1
STATEMENT 2 - 3 increment
STATEMENT 1
STATEMENT 2 - 4 increment
STATEMENT 1
STATEMENT 2 - 5 increment
STATEMENT 1
STATEMENT 2 - 6 increment (at this point,count is 6)
STATEMENT 4 - 0 decrement (it must be 6 , or it must be 7 if STATEMENT 1 is executed before this statment. Why 0??)
編輯:我的理解是基於鎖定釋放的“ happens-before”關系和隨后獲得的相同鎖定:
1)t1增量獲取鎖定,count ++(計數= 1),釋放鎖定。
2)t2減量獲得了鎖,因為它獲得了相同的鎖,所以現在計數為1,現在發生-建立關系之前(釋放時的內存狀態在獲得相同的鎖時可見),count--(count = 0),釋放鎖定。
3)t1增量打印計數(由於t1尚未獲取t2釋放的鎖,但t2遞減的計數= 0不一定對t1可見)。 在這里它是可見的,並打印0。
4)t1增量獲取鎖定並遞增,此過程一直持續到在t1中打印count = 6為止。
5)t2遞減打印計數(由於t2尚未獲得t1釋放的鎖定,因此t2的計數= 6可能不可見)。 在這里不可見。 此時可見的
count
值是0(從步驟(2)中先前的減量開始)。...
但是,執行什么順序可能導致產生條目0減量及其所有后續條目?
當線程釋放固有鎖時,該動作與任何隨后的相同鎖獲取之間將建立事前發生的關系。
來源: https : //docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
我同意預期的結果,sysout應該位於同步塊內。
這樣做解決了問題
System.out.println(count+" decrement"); // STATEMENT 4
在這種情況下將不會處於“發生之前”的情況。
關於您期望的序列,這是錯誤的,因為實際上您沒有指定強制線程等待/通知是否達到計數器值的規則。
因此執行順序是不確定的。
它可能是 :
> -1 decrement
> -2 decrement
> -3 decrement
> -4 decrement
> -5 decrement
> -6 decrement
> -7 decrement
> -8 decrement
> -9 decrement
> -10 decrement
> -9 increment
> -8 increment
> -7 increment
> -6 increment
> -5 increment
> -4 increment
> -3 increment
> -2 increment
> -1 increment
> 0 increment
如果第一個線程在終止之前沒有暫停。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.