[英]Synchronize across threads
以下代碼應確保在所有線程之間同步對“ sync”的訪問。
根據輸出,情況並非總是如此,請注意Thread-3和Thread-4如何讀取相同的sync值。
我在代碼中缺少什么嗎?
[Thread-0] before value of sync is 0
[Thread-0] after value of sync is 1
[Thread-3] before value of sync is 1
[Thread-3] after value of sync is 2
[Thread-4] before value of sync is 1
[Thread-4] after value of sync is 3
[Thread-2] before value of sync is 3
[Thread-2] after value of sync is 4
[Thread-1] before value of sync is 4
[Thread-1] after value of sync is 5
這里的代碼:
package com.mypackage.sync;
public class LocalSync implements Runnable {
private Integer sync = 0;
public void someMethod() {
synchronized (sync) {
System.out.println("[" + Thread.currentThread().getName() + "]" + " before value of sync is " + sync);
sync++;
System.out.println("[" + Thread.currentThread().getName() + "]" + " after value of sync is " + sync);
}
}
@Override
public void run() {
someMethod();
}
public static void main(String[] args) {
LocalSync localSync = new LocalSync();
Thread[] threads = new Thread[5];
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(localSync, "Thread-" + i);
threads[i].start();
}
}
}
您正在不斷更改應該在其上同步所有線程的sync對象。 因此,實際上,它們根本不同步。 將您的同步變量定為最終變量,因為每個鎖都應該如此,您將看到代碼不再編譯。
解決方案:在另一個最終對象上同步,或使用AtomicInteger更改其值,或在this
對象上同步(即,使方法同步)。
Integer是不可變的類,在執行sync ++時,您正在為Sync分配一個新引用,而其他線程可能會將該引用保存為一個較早的sync,因此會出現多線程問題。 嘗試定義一個簡單的像INTEGER這樣的MUTEX:
private final Integer MUTEX = new Integer(1);
並使用它而不是同步。
您應該在一個Object
上同步
private Object synchObj = new Object();
private Integer sync = 0;
public void someMethod() {
synchronized (synchObj) {
System.out.println("[" + Thread.currentThread().getName() + "]" + " before value of sync is " + sync);
sync++;
System.out.println("[" + Thread.currentThread().getName() + "]" + " after value of sync is " + sync);
}
}
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.