简体   繁体   English

跨线程同步

[英]Synchronize across threads

The following code should assure that access to "sync" is synchronized across all threads. 以下代码应确保在所有线程之间同步对“ sync”的访问。

According to the a output this is not always the case, notice how Thread-3 and Thread-4 are reading the same value of sync. 根据输出,情况并非总是如此,请注意Thread-3和Thread-4如何读取相同的sync值。

Am I missing something in the code? 我在代码中缺少什么吗?

[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

here the code: 这里的代码:

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

    }
}

You're constantly changing the sync object on which all threads are supposed to be synchronized. 您正在不断更改应该在其上同步所有线程的sync对象。 So, effectively, they aren't synchronized at all. 因此,实际上,它们根本不同步。 Make your sync variable final, as every lock should be, and you'll see that your code doesn't compile anymore. 将您的同步变量定为最终变量,因为每个锁都应该如此,您将看到代码不再编译。

Solution: synchronize on another, final object, or use an AtomicInteger and change its value, or synchronize on this (ie make the method synchronized). 解决方案:在另一个最终对象上同步,或使用AtomicInteger更改其值,或在this对象上同步(即,使方法同步)。

Integer is immutable class and when you are doing sync++, you are assigning a new reference to Sync and your other thread might hold the reference to an older sync and hence the issue with multithreading. Integer是不可变的类,在执行sync ++时,您正在为Sync分配一个新引用,而其他线程可能会将该引用保存为一个较早的sync,因此会出现多线程问题。 Try defining a simple MUTEX of say INTEGER like : 尝试定义一个简单的像INTEGER这样的MUTEX:

private final Integer MUTEX = new Integer(1);

And use it instead of synchronizing on sync. 并使用它而不是同步。

You should synchronize on an Object 您应该在一个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM