java 如何创建并发运行的线程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16099986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I make concurrently running threads?
提问by James
I want to have two separate threads running two different instances of different classes and I want them to execute the run command at the same time.
我想让两个单独的线程运行不同类的两个不同实例,并且我希望它们同时执行 run 命令。
I've made a practice class to demonstrate the problem I'm having. One racer counts forwards, the other counts backwards.
我做了一个练习课来演示我遇到的问题。一名赛车手向前计数,另一名赛车手向后计数。
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);
}
}
}
}
My results
我的结果
1
2
... All the way to 100
100
100
99
... All the way back down
1
What I want
我想要的是
1
100
2
99
3
98
They don't need to be taking turns like that, but they do need to be working at the same time, instead of one after the other. Any hints, advice or code snippets would be greatly appreciated.
他们不需要那样轮流,但他们确实需要同时工作,而不是一个接一个地工作。任何提示、建议或代码片段将不胜感激。
采纳答案by Andremoniy
Just add Thread.sleep(1);
in each racer
class after System.out.println()
.
只需Thread.sleep(1);
在每个racer
类中添加System.out.println()
.
i.e. it will look like this:
即它看起来像这样:
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();
}
}
}
}
回答by Joe Elleson
I think all the answers so far are missing the point.
我认为到目前为止所有的答案都没有抓住重点。
Your existing logic does enable your two threads to both execute concurrently, but this is not evident because your numbers only go up to 100, and the execution will usually stay with a specific thread for more than 1 instruction at a time, otherwise there would be a large amount of overhead in switching between the currently executing thread all the time. In your case, the JVM is deciding to execute your first thread long enough for it to print out 100 numbers before "context switching" to the 2nd thread. The JVM might choose to execute the threads differently, so the result you are seeing is not guaranteed to be the same every time.
您现有的逻辑确实使您的两个线程能够同时执行,但这并不明显,因为您的数字最多只能达到 100,并且执行通常会在特定线程中一次停留超过 1 条指令,否则会有一直在当前执行线程之间切换的大量开销。在您的情况下,JVM 决定执行您的第一个线程足够长的时间,以便在“上下文切换”到第二个线程之前打印出 100 个数字。JVM 可能会选择以不同方式执行线程,因此不能保证每次看到的结果都相同。
If you increase your numbers even to 1000 you will (probably) see the two threads interleaving somewhat. You will still have large runs where one thread prints out a lot of numbers in a row because it is more efficient for the JVM to execute one thread for a while before switching, instead of context switching between every instruction.
如果您将数字甚至增加到 1000,您(可能)会看到两个线程有些交错。您仍然会有大量运行,其中一个线程连续打印出很多数字,因为 JVM 在切换之前执行一个线程一段时间会更有效,而不是在每条指令之间进行上下文切换。
Adding Thread.sleep(1) is not a good solution as you are adding an unneccessary delay. Sure, for 100 numbers this might not be noticable but for 10000 numbers you would have a delay of 10 seconds.
添加 Thread.sleep(1) 不是一个好的解决方案,因为您正在添加不必要的延迟。当然,对于 100 个号码,这可能不会引起注意,但对于 10000 个号码,您将有 10 秒的延迟。
Is there any reason that you would require them to interleave to a higher degree than they already do? If there is then your simple model of running two threads concurrently is not sufficient. If not then just let the JVM decide the best order to run your threads in (which in the simple example you have given, means they probably won't interleave most of the time).
您是否有任何理由要求它们以比现有方式更高的程度交错?如果有,那么并发运行两个线程的简单模型是不够的。如果不是,那么就让 JVM 决定运行线程的最佳顺序(在您给出的简单示例中,这意味着它们可能不会在大多数情况下交错)。
回答by Edge
You need to write a basic wait and notify system. One task needs to notify the other that he has fished the work. Basic idea can be derived from below code. create 2 tasks, one to count forward and one to count backward
您需要编写一个基本的等待和通知系统。一项任务需要通知另一项他已经完成了这项工作。基本思想可以从下面的代码中得出。创建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();
}
}
}
}
};