5

我想让两个单独的线程运行不同类的两个不同实例,并且我希望它们同时执行运行命令。

我做了一个练习课来演示我遇到的问题。一名赛车手向前计数,另一名向后计数。

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

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

4

3 回答 3

7

我认为到目前为止所有的答案都没有抓住重点。

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

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

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

您是否有任何理由要求它们交错到比现在更高的程度?如果有那么您同时运行两个线程的简单模型是不够的。如果不是,那么只需让 JVM 决定运行线程的最佳顺序(在您给出的简单示例中,这意味着它们可能大部分时间都不会交错)。

于 2013-04-19T08:51:24.883 回答
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();
            }
        }
    }
}
于 2013-04-19T08:02:39.883 回答
-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();
        }
      }

    }
  }
};
于 2013-04-19T08:18:23.020 回答