多线程程序 - 线程相互切断

时间:2016-05-24 20:30:41

标签: java multithreading

我正在测试一些线程,试图弄清楚如何使用它们。我的问题是,我怎样才能让我的当前场景按照我的要求工作?

我希望这个程序打印出1 - 100.我有两种方法; oddNumbersevenNumbers

oddNumbers:

public static void oddNumbers() {
  new Thread(new Runnable() {
    public void run() {
      for (int i = 0; i < 100; i++) {
        if (i % 2 == 1) {
          System.out.println(i);
        }
      }
    }
  }).start();
}

evenNumbers:

public static void evenNumbers() {
  new Thread(new Runnable() {
    public void run() {
      for (int q = 0; q < 100; q++) {
        if (q % 2 == 0) {
          System.out.println(q);
        }
      }
    }
  }).start();
}

main method

public static void main(String[] args) {
  evenNumbers();
  oddNumbers();
}

因此,根据我的理解,方法oddNumbersevenNumbers正在不同的线程上运行。所以,如果他们是,那么为什么我的输出不是1-100?

这是我得到的输出:

0
2
4
6
.
.
.
50
1
3
5
.
.
.
99
52
54
56
.
.
.
100

evenNumbers循环的大约一半时,oddNumbers循环将其切断。为什么会发生这种情况,如何设置它以便打印1-100?

提前致谢!

2 个答案:

答案 0 :(得分:3)

因为你没有告诉线程等待剩下的参与者。

很难判断下一个线程是否在启动后继续工作或启动需要多长时间。它可能是几个cpu周期或2秒。

您想要实时关键应用的准确指令时间吗?启动fpga编程。

对于这个java pc程序,你可以使用循环障碍只是为了让它们一起执行步骤,而没有任何首要的优先级。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class Demo {
    public static CyclicBarrier barrier = new CyclicBarrier(2);
    public static void oddNumbers() {
          new Thread(new Runnable() {
            public void run() {
              for (int i = 0; i < 100; i++) {
                  try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (i % 2 == 1) {
                  System.out.println(i);
                }
              }
            }
          }).start();
        }


        public static void evenNumbers() {
          new Thread(new Runnable() {
            public void run() {
              for (int q = 0; q < 100; q++) {
                  try {
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                if (q % 2 == 0) {
                  System.out.println(q);
                }
              }
            }
          }).start();
        }


        public static void main(String[] args) {
          evenNumbers();
          oddNumbers();
        }
}
这里创建了

barrier实例,可以容纳2个线程,所以每2个等待操作重置它,线程可以在下一次迭代时再次等待它。

但是,它有可能输出:

1
0
3
2
5
4
...

而不是

0
1
2
3

可以使用第三个操作在打印到控制台之前组合2个线程结果来解决。

这里的硬度是你要求在多线程环境中进行连续操作。

答案 1 :(得分:1)

我知道你不希望他们被交替,只要明白为什么每一个都被执行了这么久。

该决定由操作系统的调度程序执行。它决定何时切换到另一个线程。您的示例就是您的线程非常小,执行速度非常快。

调度程序将 power 执行到线程一段时间,问题是,该时间足以显示如此多的循环次数,因此它们不会被多次切换。

如果你运行时间更长,使用更大的数字,你会得到更好的结果。或者,您也可以在打印之前使循环花费更长时间,添加一些需要时间的微积分,这样它就不会连续打印那么多数字。