如何同时运行线程?

时间:2013-04-19 07:59:32

标签: java multithreading concurrency runnable

我希望有两个独立的线程运行不同类的两个不同实例,我希望它们同时执行run命令。

我做了一个练习课来证明我遇到的问题。 一名赛车手向前跑,另一名则向后跑。

public class testCount {

    public static void main(String args[]) {
        testCount countCompetition = new testCount();
        countCompetition.run();
    }

    public void run() {
        (new Thread(new racer1())).start();
        (new Thread(new racer2())).start();
    }

    public class racer1 implements Runnable {
        public void run() {
            for(int x = 0; x < 100; x++) {
                System.out.println(x);
            }
        }
    }
    public class racer2 implements Runnable {
        public void run() {
            for(int y = 100; y > 0; y--) {
                System.out.println(y);
            }
        }
    }
}

我的结果

1
2
... All the way to 100
100
100
99
... All the way back down
1

我想要什么

1
100
2
99
3
98

他们不需要像这样轮流,但他们确实需要同时工作,而不是一个接一个地工作。 任何提示,建议或代码片段都将不胜感激。

3 个答案:

答案 0 :(得分:7)

我认为到目前为止所有答案都没有提及。

您现有的逻辑确实可以使两个线程同时执行,但这并不明显,因为您的数字最多只能达到100,并且执行通常会在特定线程中保留一次超过1条指令,否则总是在当前正在执行的线程之间切换会产生大量开销。在您的情况下,JVM决定执行您的第一个线程足够长的时间,以便在“上下文切换”到第二个线程之前打印出100个数字。 JVM可能会选择以不同方式执行线程,因此您看到的结果不能保证每次都相同。

如果你将数字增加到1000,你(可能)会看到两个线程交错。您仍然会有大型运行,其中一个线程连续打印出大量数字,因为JVM在切换之前执行一个线程更有效,而不是在每个指令之间切换上下文。

添加Thread.sleep(1)不是一个好的解决方案,因为您要添加一个不必要的延迟。当然,对于100个数字,这可能不是很明显,但对于10000个数字,你会有10秒的延迟。

你有没有理由要求他们交换到比他们已经做的更高的程度?如果有,那么同时运行两个线程的简单模型是不够的。如果没有,那么让JVM决定运行你的线程的最佳顺序(在你给出的简单示例中,意味着它们可能不会在大多数时间交错)。

答案 1 :(得分:1)

只需在Thread.sleep(1);之后的每个racer课程中添加System.out.println()

即。它看起来像这样:

public class racer1 implements Runnable {
    public void run() {
        for(int x = 0; x < 100; x++) {
            System.out.println(x);
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

答案 2 :(得分:-1)

您需要编写基本的等待并通知系统。一项任务需要通知对方他已经完成了工作。基本思想可以从下面的代码中得出。创建2个任务,一个向前计数,一个向后计数

Runnable task = new Runnable() {
  public void run() {
    System.out.println("woohooTwo");
    synchronized (t) {
      while (true) {
        System.out.println("---" + Thread.currentThread().getName() + "--" + t.i.getAndIncrement());
        t.notifyAll();

        try {
          Thread.sleep(1000);
          t.wait();
        } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
      }

    }
  }
};