Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的多线程未按预期工作_Java_Multithreading - Fatal编程技术网

Java中的多线程未按预期工作

Java中的多线程未按预期工作,java,multithreading,Java,Multithreading,第一个代码并不总是显示总和为1000,因此我找到了解决问题的方法,但为什么第一个代码不起作用?结果是高度不一致的,我知道在这种情况下使用synchronized没有任何作用,但我只是在尝试 class Thread1 extends Thread{ int[] count; int[] event; Thread1(int[] event, int[] count){ this.event=event; this.count=count;

第一个代码并不总是显示总和为1000,因此我找到了解决问题的方法,但为什么第一个代码不起作用?结果是高度不一致的,我知道在这种情况下使用synchronized没有任何作用,但我只是在尝试

class Thread1 extends Thread{
    int[] count;
    int[] event;
    Thread1(int[] event, int[] count){
        this.event=event;
        this.count=count;
    }
    public void run(){
        for(int i=0; i<500; i++){

            int x = event[i];
            synchronized (count){
                count[x]++;
            }
        }
    }
}

class Thread2 extends Thread{
    int[] count;
    int[] event;
    Thread2(int[] event, int[] count){
        this.event=event;
        this.count=count;
    }
    public void run(){
        for(int i=500; i<1000; i++){

            int x = event[i];
            synchronized (count){
                count[x]++;
            }

        }
    }
}

public class Learning {

    public static void main(String[] args) {
        Random random = new Random();
        int[] event = new int[1000];

        for(int i=0; i<event.length; i++){
            event[i] = random.nextInt(3);
        }

        Thread1 a = new Thread1(event, new int[3]);
        Thread2 b = new Thread2(event, new int[3]);

        a.start();
        b.start();

        int second = a.count[1]+b.count[1];
        int third = a.count[2]+b.count[2];
        int first = a.count[0]+b.count[0];

        System.out.println(first);
        System.out.println(second);
        System.out.println(third);

        System.out.println("SUM--> "+(first+second+third));
    }
}

class Thread1扩展了线程{
int[]计数;
int[]事件;
线程1(int[]事件,int[]计数){
这个。事件=事件;
这个.count=count;
}
公开募捐{

对于(int i=0;i,
Thread1
Thread2
类使用各自的
count
对象进行同步

问题在于,您可以这样实例化它们:

    Thread1 a = new Thread1(event, new int[3]);
    Thread2 b = new Thread2(event, new int[3]);
看到了吗

您正在将不同的数组传递给两个线程。如果两个线程使用不同的对象作为其
计数,则无法实现互斥或正确的内存可见性


在进一步检查中,似乎无论如何都不需要同步块。(您不需要互斥,并且您可以得到某些保证,子线程将看到正确初始化的数组,因为
start()
以前发生过。)

但是,很明显,有必要将主线程中的两个子线程连接起来,原因如下:

  • 如果不
    join()
    ,则无法在主线程查看结果之前确定子线程是否已完成

  • 如果不
    join()
    ,则存在潜在的内存异常…即使子线程在主线程查看计数之前都已终止。(
    join()
    调用在子线程和主线程之间施加了“发生在前”关系。)


  • 您尝试使用
    stop()
    的解决方案是假的,原因如下:

  • stop()
    方法不推荐使用,因为它很危险。不应使用它

  • stop()
    方法没有指定的同步效果

  • 基于文档化的语义(例如它们),调用
    stop()
    不应该解决问题

  • 一般来说,“随机尝试”并不是修复并发错误的好策略。随机尝试很有可能不会修复错误,而是将其从频繁出现的错误转变为很少出现的错误……或者只在不同的Java平台上进行测试

    为什么它看起来有效

    看起来子线程在停止之前就终止了。但这只是运气。如果您扩大子线程所做的工作量,则不太可能发生这种情况。

    添加-a.stop();b.stop();a.start()之后;b.start();修复了问题


    但我不明白为什么。

    欢迎来到stackoverflow。请直接将所有相关信息添加到您的帖子中,避免截图。您可能还需要检查。我不明白截图的意义。我也不明白发布两份100多行几乎相同的代码副本的意义……而不解释它们是如何产生的不同。您是否尝试加入线程?在
    a.start()
    b.start()
    之后,您可以添加
    a.join()
    b.join()
    确保它们在计算
    和之前都终止
    第一个代码和第二个代码之间的区别是什么?这看起来像是一个非常标准的竞态条件,其中第一个、第二个和第三个使用的值根据两个线程是否完成执行而变化。我认为是指线程1中的
    count[0]
    和线程2中的
    count[0]
    之和是
    事件中所有
    0
    s的数量:
    int first=a.count[0]+b.count[0]所以OP是正确的,所有0、所有1和所有2的总和应该是
    1000
    。除非线程没有正确终止?但是,我不确定我是否理解这个问题如果你是正确的,错误的同步是>>他们甚至需要同步吗?Thread1处理“event”的前500个条目,查看值和计数递增。类似地,Thread2处理“event”的下500个条目,并在计数数组中递增。最后,我尝试添加两个计数数组。@StephenC另一个问题不是
    join
    ing.1)这是一个随机的非修复程序。通过做出与真正的一个或多个错误无关的更改,很容易使多线程程序看起来正常工作。2)不要调用
    Thread。stop()
    是不推荐的。因为当你到达它执行
    a.stop()
    b.stop()的行时
    它很可能已经完成了执行。尽管正如Stephen C所提到的,这是随机的。假设您的线程
    a
    需要10秒才能完成-但是您已经到达了行
    a.stop()
    1秒后-然后它将强制停止,并且只完成10%。因此:这不是解决方案,而是随机的。