簡體   English   中英

run方法中的同步塊

[英]Synchronized Block inside the run method

在run方法中使用synchronized塊是否有意義? 我認為它確實如此,只要我使用相關的鎖,而不是包含此run方法的Runnable實例。 在stackoverflow上閱讀類似問題的答案似乎證實了這一點。 我嘗試編寫一些簡單的代碼來測試它,run方法中的synchronized塊不會阻止數據損壞:

public class Test {

    public Test() {
        ExecutorService es = Executors.newCachedThreadPool();
        for (int i = 0; i < 1000; i++) {
            es.execute(new Runnable() {
                @Override
                public void run() {
                    synchronized (lock) {
                        sum += 1;
                    }
                }
            });
        }
        es.shutdown();
        while(!es.isTerminated()) {
        }
    }
    private int sum = 0;
    private final Object lock = new Object();

    public static void main(String[] args) {
        Test t = new Test();
        System.out.println(t.sum);
    }
}

為什么此代碼生成錯誤的結果? 這是因為同步塊還是其他一些錯誤? 我覺得我在這里缺少一些基本的東西。

您的執行程序可能會遇到某種意外錯誤。 如果發生這種情況,你就不會知道它,因為你沒有得到任何返回值來檢查。

嘗試切換到submit()而不是 execute()並存儲Executor為您提供的Future實例列表。 如果最終總和小於1000,則迭代期貨並獲得每個期貨。 如果出現異常,您將看到該特定runnable任務發生了什么。

除了你看起來不錯的簡單示例之外,你應該注意Runnables中的同步,以防止它們在一個Runnable等待某個資源僅由稍后尚未啟動的隊列中的另一個Runnable釋放時相互阻塞。因為當前等待的Runnable必須先完成。

但是,如果有足夠的工作線程執行作業,則不太可能發生這種情況。

暫無
暫無

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

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