java中同一方法上的多线程 package-newpackage; 导入java.util.logging.Level; 导入java.util.logging.Logger; 课堂测试{ 公共int in=0; void helper(){ 线程t1=新线程( () -> { 添加(); } ); 螺纹t2=新螺纹( () -> { 添加(); } ); t1.start(); t2.start(); 试一试{ t1.join(); t2.连接(); }捕获(中断异常例外){ Logger.getLogger(test.class.getName()).log(Level.SEVERE,null,ex); } } void add(){ 对于(int i=0;i

java中同一方法上的多线程 package-newpackage; 导入java.util.logging.Level; 导入java.util.logging.Logger; 课堂测试{ 公共int in=0; void helper(){ 线程t1=新线程( () -> { 添加(); } ); 螺纹t2=新螺纹( () -> { 添加(); } ); t1.start(); t2.start(); 试一试{ t1.join(); t2.连接(); }捕获(中断异常例外){ Logger.getLogger(test.class.getName()).log(Level.SEVERE,null,ex); } } void add(){ 对于(int i=0;i,java,multithreading,Java,Multithreading,我想要的是从不同的线程同时运行相同的方法 但是上面给出的代码没有给出正确的结果。它给出的输出小于1560(780+780)。我如何才能实现这一点 提前谢谢 您遇到了并发程序的经典问题之一。没有正确同步的可变共享状态。中的变量由两个线程同时修改,而且i+=1操作不是原子操作。事实上,情况是: package newpackage; import java.util.logging.Level; import java.util.logging.Logger; class test {

我想要的是从不同的线程同时运行相同的方法

但是上面给出的代码没有给出正确的结果。它给出的输出小于1560(780+780)。我如何才能实现这一点


提前谢谢

您遇到了并发程序的经典问题之一。没有正确同步的可变共享状态。中的变量
由两个线程同时修改,而且
i+=1
操作不是原子操作。事实上,情况是:

package newpackage;

import java.util.logging.Level;
import java.util.logging.Logger;

class test {

    public int in = 0;

    void helper() {

        Thread t1 = new Thread(
                ()
                -> {

            add();

        }
        );

        Thread t2 = new Thread(
                ()
                -> {

            add();

        }
        );
        t1.start();
        t2.start();
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException ex) {
            Logger.getLogger(test.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    void add() {
        for (int i = 0; i < 40; i++) {
            in += i;
            try {
                Thread.sleep(50);
            } catch (InterruptedException ex) {
                Logger.getLogger(test.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

}

public class Main {

    public static void main(String[] args) {
        test a = new test();
        a.helper();
        System.out.println(a.in);
    }
}
现在的问题是两个线程同时运行,因此可能发生以下情况:

int temp = i + 1;
i = temp;
正如你所看到的,我们增加了两次,但我只增加了1。此外,由于您的变量不是易失性的,或者其他任何东西,因此线程之间没有可见性保证,这意味着如果线程1修改变量,JVM就不能保证让读取该变量的任何其他线程看到该更改

要正确执行此操作,您需要使用某种类型的同步辅助工具,最简单的方法是
synchronized
块。然而,在这种情况下,这将破坏并行相加的目的,因为同步将使事情以一定的开销按顺序有效地运行


如果您真的想并行地添加内容,请查看Java8流或Java7中的Fork-Join框架。然而,请注意,这样做只会对足够大的数据集产生好处,因为并行运行总是会带来一些开销。

关于“正确的结果”,您的预期输出是什么,以及您观察到的输出是什么?另外,你的方法什么都不做——请发布真实的代码,我们可以编译、测试和修改的代码。“没有给出正确的结果”我想你的意思是它没有给出你期望的结果,因为它确实做到了Java规范所说的。你认为它应该做什么,它应该做什么?@AndyTurner抱歉。我这样做是为了简单。现在编辑,谢谢。知道了。那么如果我的add()函数不能在同一个对象/变量上工作呢。假设我的add()函数接受fileName的参数,然后将其写入。因此,如果我将两个不同的文件名从不同的线程传递给同一个函数,是否会有任何形式的损坏?不,可以从不同的线程并行地写入不同的文件,尽管这最终取决于底层的文件系统。
// assuming i == 3
int temp = i + 1; // Thread 1, temp == 4
int temp = i + 1; // Thread 2, temp == 4
i = temp; // Thread 2, i == 4
i = temp; // Thread 1, i == 4