【问题标题】:My code is not threadsafe, why are my threads synchronized?我的代码不是线程安全的,为什么我的线程是同步的?
【发布时间】:2018-01-29 15:51:26
【问题描述】:

所以我目前正在尝试理解并发性。在我的代码中,我创建了一个具有 int var 的类“Summer”。它的方法 sumUP 将 var 增加 2000000。 我的第二个类是一个以 Summer 作为参数并调用其方法 sumUp 的线程。 这两个对象都在我的主线程中初始化并启动。

经过我的理解,结果应该是任意的,基本上是给我的随机数。主线程和第二线程创建自己的变量副本并独立更改它。

我的代码根本不是线程安全的,没有易失性,没有同步,但答案始终是 4000000。你能解释一下我的错误还是 eclipse 为我修复了线程安全?在此先感谢:)

public class Main {

public static void main(String[]agrs) {

    Summer summer = new Summer();

    Thread t1 = new Thread(new MyRunnable(summer));

    summer.sumUp();
    t1.start();
}


}


public class MyRunnable implements Runnable {

private Summer summer;

public MyRunnable(Summer summer) {
    this.summer = summer;
}

@Override
public void run() {

    System.out.println(Thread.currentThread().getName() + " hat gestartet R");

    summer.sumUp();

    System.out.println("Thread val =" + summer.val);

}

}


public class Summer {

public int val;

public void sumUp() {
    for(int i=0; i<2000000; i++) {
        increment();
    }

    System.out.println("MainThread val = " + val);
}

private void increment() {
    val++;
}

}

(我知道 var 应该是私有的,但这样更快:))

【问题讨论】:

  • 这与 Eclipse 无关,它只是您的开发环境。这个问题是关于 Java 是如何工作的。

标签: java multithreading concurrency


【解决方案1】:

只有在sumUp 的第一次运行完成后才启动线程,将值保留为 2000000。首先启动线程可能会遇到“预期的”问题。

PS:这与 Eclipse 无关。

【讨论】:

    【解决方案2】:

    Thread.start 创建一个“发生在关系之前”。引用此Question

    当一个语句调用 Thread.start() 时,每个语句都有一个 与该语句的发生之前的关系也有 与新执行的每个语句的发生前关系 线。导致创建新代码的代码的影响 线程对新线程可见

    所以在初始化线程缓存的时候,summer的值已经是2000000了。

    【讨论】:

    • 最佳答案,因为它实际上解释了同步的位置。请注意,这是一个 API 功能,实际上并不是语言的一部分。 java.util.concurrency 也有许多指定发生前关系的类。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 2018-04-12
    • 2010-10-15
    相关资源
    最近更新 更多