跨线程同步

时间:2014-11-24 13:04:48

标签: java multithreading

以下代码应确保在所有线程之间同步对“sync”的访问。

根据输出结果并非总是如此,请注意Thread-3和Thread-4如何读取相同的同步值。

我在代码中遗漏了什么吗?

[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();
        }

    }
}

3 个答案:

答案 0 :(得分:6)

您不断更改应同步所有线程的同步对象。所以,实际上,他们根本没有同步。将您的同步变量设为最终,因为每个锁都应该是,并且您将看到您的代码不再编译。

解决方案:同步另一个最终对象,或使用AtomicInteger并更改其值,或在this上同步(即使方法同步)。

答案 1 :(得分:3)

Integer是不可变类,当你进行sync ++时,你正在为Sync分配一个新的引用,而你的另一个线程可能会保存对旧同步的引用,因此也存在多线程的问题。尝试定义一个简单的MUTEX,例如INTEGER:

private final Integer MUTEX = new Integer(1);

并使用它而不是同步同步。

答案 2 :(得分:0)

您应该在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);
    }
}

...