[英]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.