簡體   English   中英

Java同步(針對特定示例)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM