我有兩個線程,每個線程都有自己的計數器:線程A有counterA,線程B有counterB。每個線程必須使用兩個計數器:線程A必須使用counterA和counterB,而線程B必須使用兩者。 我正在使用AtomicInteger並共享兩個線程之間的計數器,我將它們作爲參數傳遞給線程,並且每個線程將兩個計數器存儲在專用字段中。安全發佈,參數傳遞
// ...
AtomicInteger counterA = new AtomicInteger(0);
AtomicInteger counterB = new AtomicInteger(0);
Thread tA = new Thread(new RunnableA(counterA, counterB));
Thread tB = new Thread(new RunnableB(counterA, counterB));
// ... in the constructor of RunnableA ...
RunnableA(AtomicInteger counterA, AtomicInteger counterB) {
this.counterA = counterA;
this.counterB = counterB;
}
//...
// The same for RunnableB
這是兩個計數器的safe publishing? 安全發佈是必要的,因爲對對象的引用不夠安全,無法在線程之間共享對象。 如何在這種情況下實現安全發佈?
在此先感謝。
「我不能馬上看到,可能是」 - 如果計數器被新創建的線程作爲的Runnable的實例變量的外部訪問。在構造函數中初始化的值在被訪問之前並不保證是可見的,除非例如聲明至少一個實例變量爲final,請參閱https://shipilev.net/blog/2014/safe-public-construction/ –
好吧......但是在構造函數返回之前,這些變量怎麼能被* anything *訪問?查看構造函數的代碼。 (我知道安全發佈意味着什麼,'final'只是實現它的一種方法。) –
「當start()被調用時,在當前線程的start()調用和新線程的run ()調用,這意味着保證將變量安全地發佈到子線程本身。「這是我覺得有用的一點。例如,儘管Runnable是在主線程中構建的,但是不需要在Runnable中聲明「參數變量」(this.counterA,this.counterB)作爲final,然後這些參數變量可以在創建的線程。 –