具有一個共享物件的多個執行緒
在這個例子中,我們只有一個物件,但它在不同的執行緒之間共享/執行。普通使用欄位來儲存狀態是不可能的,因為另一個執行緒也會看到(或者可能看不到)。
public class Test {
public static void main(String[] args) {
Foo foo = new Foo();
new Thread(foo, "Thread 1").start();
new Thread(foo, "Thread 2").start();
}
}
在 Foo 中,我們從零開始計算。我們將當前的數字儲存在靜態可訪問的 ThreadLocal 物件中,而不是將狀態儲存到欄位中。請注意,此示例中的同步與 ThreadLocal 的使用無關,而是確保更好的控制檯輸出。
public class Foo implements Runnable {
private static final int ITERATIONS = 10;
private static final ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return 0;
}
};
@Override
public void run() {
for (int i = 0; i < ITERATIONS; i++) {
synchronized (threadLocal) {
//Although accessing a static field, we get our own (previously saved) value.
int value = threadLocal.get();
System.out.println(Thread.currentThread().getName() + ": " + value);
//Update our own variable
threadLocal.set(value + 1);
try {
threadLocal.notifyAll();
if (i < ITERATIONS - 1) {
threadLocal.wait();
}
} catch (InterruptedException ex) {
}
}
}
}
}
從輸出中我們可以看到每個執行緒都為自己計算,並且不使用另一個的值:
Thread 1: 0
Thread 2: 0
Thread 1: 1
Thread 2: 1
Thread 1: 2
Thread 2: 2
Thread 1: 3
Thread 2: 3
Thread 1: 4
Thread 2: 4
Thread 1: 5
Thread 2: 5
Thread 1: 6
Thread 2: 6
Thread 1: 7
Thread 2: 7
Thread 1: 8
Thread 2: 8
Thread 1: 9
Thread 2: 9