簡體   English   中英

使用靜態對象鎖時不起作用?

[英]When using static object lock doesn't work?

我是並發的新手,我正在嘗試理解同步塊:

public static int count1 = 0;
public static Object lock1 = new Object();

public static void add(){
        synchronized (lock1) {
            count1++;
        }
}

我的問題是lock1,它不起作用,當方法開始打印顏色時,它會隨機打印它們,所以我認為問題出在同步塊中,因為我看了一些關於這個的教程,他們都說鎖定對象必須是靜態的,所以不會發生干擾,但在這里我沒有看到,為什么?

這是打印每個線程顏色的方法:

public static void compute(){
        String color = null;
        switch (Thread.currentThread().getName()) {
            case "First Count Down":
                color = TextColors.ANSI_YELLOW;
                break;
            case "Second Count Down":
                color = TextColors.ANSI_MAGENTA;
                break;
        }
        for (int i=0;i<100;i++) {
            System.out.println(color + Thread.currentThread().getName() + "is Running");
            //add();
            add();
        }
    }

這是線程:

public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                compute();
            }
        });
        t1.setName("First Count Down");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                compute();
            }
        });
        t2.setName("Second Count Down");

        t1.start();
        t2.start();

        try{
            t1.join();
            t2.join();

        }catch (InterruptedException io){
            io.printStackTrace();

        }

        System.out.println("Count1 = " + count1 + " Count2 = " + count2);

    }

對不起,如果我的英語不好,我不是母語人士,提前致謝

首先,我想現在我明白你的問題了。 您試圖在不干擾其他線程的行的情況下打印出您的行。

為了實現這一點,你必須“保護”你的代碼部分,它打印出一行,而不是同時從另一個線程打印出另一行。

可以通過同步這些代碼行來完成保護。

您當前僅同步該計數器的添加。

您的鎖(您鎖定的對象,即 new Object() 的唯一實例)是靜態的,您無需在代碼中更改它,因此它必須有效。

public static Object lock1 = new Object();

您可以將變量設置為 final 以使其不可變,但目前這不是問題。 不過,我會建議這樣做。

鎖意味着,如果任何其他線程登陸(執行)同一行代碼(同步塊的開頭),它們將不會得到執行,直到阻塞線程放棄它的鎖。 只有當他們持有並請求相同的鎖時,這才是正確的。 由於您只使用相同的 new Object() 實例,因此您的鎖應該沒問題。

目前,您的代碼已構建為 add() 方法基本上等待,直到其中一個線程正在計數。

如果要更改它以便單獨打印行,請嘗試像這樣同步“行打印塊”:

    synchronized (lock1) {
        System.out.println(color + Thread.currentThread().getName() + "is Running");
        add();
    }

並且讓計數不同步。

private static void add(){
    count1++;
}

這會起作用,但大多數情況下您不想讓您的 add() 方法不同步。 它可以從其他線程執行,誰知道呢。 但是對於您的情況,這些更改會有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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