Java线程输出答案错误。

huangapple go评论63阅读模式
英文:

Java Thread outputting answer wrong

问题

package task1;

import java.lang.Thread;

public class Counter implements Runnable {
    int num;
    boolean odd;
    boolean even;

    public Counter(int i, boolean odd, boolean even) {
        this.num = i;
        this.odd = odd;
        this.even = even;
    }

    @Override
    public void run() {
        if (odd == true & even == false) {
            System.out.print("\n奇数\n");

            for (int j = this.num; j <= 10; j += 2) {
                System.out.print(j + " ");
            }
        } else if (odd == true & even == true) {
            System.out.print("\n奇偶数配对\n");

            for (int j = this.num; j <= 10; j += 2) {
                try {
                    Thread.sleep(600);
                } catch (InterruptedException ex) {
                    System.out.println("睡眠被中断!");
                }

                System.out.print(j + " " + (j + 1) + " | ");
            }
        }
    }
}

class OddEvenNums {
    public static void main(String[] args) {
        Counter odd = new Counter(1, true, false);
        Counter evenodd = new Counter(1, true, true);

        Thread oddThread = new Thread(odd);
        Thread evenOddThread = new Thread(evenodd);
        oddThread.start();
        evenOddThread.start();
    }
}
英文:
package task1;
import java.lang.Thread;
public class Counter implements Runnable{
int num;
boolean odd;
boolean even;
public Counter(int i,boolean odd, boolean even){
this.num=i;
this.odd=odd;
this.even=even;
}
@Override
public void run() {
if(odd==true&amp;even==false){
System.out.print(&quot;\nOdd numbers\n&quot;);
for(int j=this.num; j&lt;=10; j+=2){  
System.out.print(j + &quot; &quot;);
}
}
else if (odd==true&amp;even==true){
System.out.print(&quot;\nEven and odd numbers paired\n&quot;);
for(int j=this.num; j&lt;=10; j+=2){
try {
Thread.sleep(600);
} catch (InterruptedException ex) {
System.out.println(&quot;The sleeping has been interruped!&quot;);
}
System.out.print(j + &quot; &quot; + (j+1)+&quot; | &quot;);
}
}
}
}
class OddEvenNums {
public static void main(String[] args) {
Counter odd = new Counter(1,true,false);
Counter evenodd = new Counter(1,true,true);
Thread oddThread = new Thread(odd);
Thread evenOddThread = new Thread(evenodd);
oddThread.start();
evenOddThread.start();
}
}

Basically this code just has two threads that either print out the odd numbers from 1-10 or print out the odd and the even numbers paired

However the output comes out like

run:
Odd numbers
Even and odd numbers paired
1 3 5 7 9 1 2 | 3 4 | 5 6 | 7 8 | 9 10 |

Instead of what I was hoping for which would be

run:
Odd numbers
1 3 5 7 9
Even and odd numbers paired
1 2 | 3 4 | 5 6 | 7 8 | 9 10 |

I am confused about what I have done wrong to cause it to be outputted like this

答案1

得分: 1

两个线程并行运行,而不是一个接着一个运行(这正是线程存在的目的)。这就是为什么它们的输出会混合在一起。

试图解释你所看到的输出: "odd" 线程稍微领先一点,让它首先打印出 "Odd numbers"。然后 "oddeven" 线程加入并打印出 "Even and odd numbers paired"。接下来,"oddeven" 线程休眠了 600 毫秒(在计算机时间中相当于半个世纪),这给了 "odd" 线程足够的时间来完成打印它的序列。一旦经过了 600 毫秒,"oddeven" 再次启动并打印出它自己的序列(每对数字之间延迟 600 毫秒,但这已经不重要了,因为 "odd" 线程早已完成)。

然而,这绝不是确定性的。也就是说,如果你多次运行程序,可能会看到完全不同的字符串输出序列。

英文:

Both Threads are running in parallel, not one after another (that's the purpose of Threads in the first place). That's why their output gets mixed up.

Trying to explain the output that you're seeing: The "odd" Thread gets a tiny bit of a head start, letting it print "Odd numbers" first. Then the "oddeven" Thread kicks in and prints "Event and odd numbers paired". Next thing, "oddeven" sleeps for 600 milliseconds (= half an eternity in computer time), giving "odd" all the time it needs to complete printing its sequence. Once the 600ms are elapsed, "oddeven" kicks back in and prints its own sequence (delaying another 600ms between each pair, but that doesn't really matter any more, as "odd" has long completed).

This is by no means deterministic, though. Meaning, if you run the program a couple of times you might see completely different sequences of String output.

答案2

得分: 0

输出完全符合预期,尽管其中的步骤顺序可能有点随机。这里发生的情况是:

oddThread写入“奇数”

evenOddThread写入“偶数和奇数配对”

oddThread写入“1 3 5 7 9”(无换行符)

evenOddThread写入“1 2 | 3 4 | 5 6 | 7 8 | 9 10 |”

所以,从本质上说,你没有做错任何事情。但是你没有考虑同时运行两个线程时会发生什么。要么不这样做(在启动evenOddThread之前等待oddThread完成,通过调用oddThread.join()),要么在其中添加一些同步以确保输出是原子写入的。你有些幸运能够获得你所得到的输出。也有可能出现以下情况:

  • 一直工作,直到随机出现问题
  • 更糟糕地混合输出,例如1 1 2 3 | 3 4 5 7 | 5 6 9 | 7 8 | 9 10 |
  • 将evenOddThread的输出放在oddThread之上(这可能不太可能,但是无法保证线程的调度顺序)
英文:

The output is totally expected, although it is a bit random in what order exactly stuff happens. What is happening here is:

oddThread writes "Odd numbers"

evenOddThread writes "Even and odd numbers paired"

oddThread writes "1 3 5 7 9" (without newline)

evenOddThread writes "1 2 | 3 4 | 5 6 | 7 8 | 9 10 |"

So, you did nothing wrong per se. But you didn't think about what would happen when you run both threads concurrently. Either don't do that (wait for oddThread to be finished before starting evenOddThread, by calling oddThread.join()), or put some synchronization in there to make sure the output is written atomically. You are somewhat lucky to get the output you got. I could also have:

  • Just worked, until it randomly doesn't
  • mixed the output up even worse, like 1 1 2 3 | 3 4 5 7 | 5 6 9 | 7 8 | 9 10 |
  • put evenOddThread output above oddThread (probably unlikely but there is no guarantuee for how the threads get scheduled)

huangapple
  • 本文由 发表于 2020年8月17日 14:43:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/63445794.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定