具有一个共享对象的多个线程
在这个例子中,我们只有一个对象,但它在不同的线程之间共享/执行。普通使用字段来保存状态是不可能的,因为另一个线程也会看到(或者可能看不到)。
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