Java 线程数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26540036/
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
Array of threads?
提问by Syrne
So I am having an issue understanding how to avoid sequential execution of threads. I am attempting to create an array of threads and execute the start() and join() functions in separate loops. Here's a code example of what I have now:
所以我在理解如何避免线程的顺序执行时遇到了问题。我正在尝试创建一个线程数组并在单独的循环中执行 start() 和 join() 函数。这是我现在拥有的代码示例:
private static int[] w;
static class wThreads implements Runnable {
private final int i;
public wThreads(int i) {
this.i = i;
}
//Set member values to 1
@Override
public void run() {
//doing specific stuff here
}
}
And here's where the threads are created in main:
这是在 main 中创建线程的地方:
int argSize = Integer.parseInt(args[0]);
w = new int[argSize];
//Initialize w
for (int i = 0; i < argSize; i++) {
wThreads wt = new wThreads(i);
for (int j = 0; j < argSize - 1; j++) {
Thread t = new Thread(wt);
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
So apparently this is not an example of threads working in parallel. They are waiting for each other to finish. I know that the join() and start() calls should be in different loops, but how can I reference the thread in a different loop than the one it's initially created in?
所以显然这不是线程并行工作的例子。他们在等待对方完成。我知道 join() 和 start() 调用应该在不同的循环中,但是如何在与最初创建的循环不同的循环中引用线程?
Do I need to create an array of threads in the class declaration? Should the loops be in there as well, and outside of main?
我需要在类声明中创建一个线程数组吗?循环也应该在那里,并且在 main 之外?
I'm quite confused and any info would be appreciated. Thank you!
我很困惑,任何信息将不胜感激。谢谢!
采纳答案by Dylan
You can't do the join inside the loop where you are starting them (you can but as you have found, there is no parallelism). Create an array for the threads, start them in one loop and then create a second loop that does the join call. I don't think you want the inner for at all.
您不能在启动它们的循环内进行连接(您可以,但正如您发现的那样,没有并行性)。为线程创建一个数组,在一个循环中启动它们,然后创建执行 join 调用的第二个循环。我认为你根本不需要内在。
Thread myThreads[] = new Thread[argsize];
for (int j = 0; j < argSize; j++) {
myThreads[j] = new Thread(new wThreads(j));
myThreads[j].start();
}
for (int j = 0; j < argSize; j++) {
myThreads[j].join(); //todo add catch exception
}
I suspect you want to do this yourself, but the standard way is using Executor, Thread Pools and such, see Oracle Tutorials
我怀疑你想自己做这件事,但标准的方法是使用执行器、线程池等,请参阅Oracle 教程
回答by dasblinkenlight
Do I need to create an array of threads in the class declaration?
我需要在类声明中创建一个线程数组吗?
You need an array or some other collection. It is not necessary to put it at the class declaration level - it might very well be local:
您需要一个数组或其他一些集合。没有必要将它放在类声明级别 - 它很可能是本地的:
w = new int[argSize];
//Initialize w
Thread[] t = new Thread[argSize];
// Create and start threads in the first loop
for (int i = 0; i < argSize; i++) {
t[i] = new Thread(new wThreads(i));
t[i].start();
}
// Let the threads run concurrently,
// and wait for them to finish in a second loop
for (int i = 0; i < argSize; i++) {
try {
t[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
回答by TheSuper
When you call join()
on a thread, you are telling your program to wait until the thread is done executing, then to destroy the thread. Obviously, then, we want to spin up a bunch of new threads, let them run, and join them later. A thread is just a value like any other, and you can store it in a variable. So, in this case, let's make a new array of Threads:
当您调用join()
一个线程时,您是在告诉您的程序等待该线程完成执行,然后销毁该线程。显然,我们想要启动一堆新线程,让它们运行,然后再加入它们。线程只是一个值,就像其他任何值一样,您可以将它存储在一个变量中。所以,在这种情况下,让我们创建一个新的线程数组:
Thread[] myThreads; // New array of threads
myThreads = new Thread[argSize]; // Same size as our int array
for (int i = 0; i < argSize; i++) {
wThreads wt = new wThreads(i);
// you don't need the second loop.
myThreads[i] = new Thread(wt);
t.start(); // Spins up a new thread and runs your code
}
Now, if you want to join the threads in another function, you must make your array of threads a member variable. Otherwise, you can make it as-is.
现在,如果要在另一个函数中加入线程,则必须将线程数组设为成员变量。否则,您可以按原样制作。
When you want to join your threads, just loop through the array and call join()
on each member.
当你想加入你的线程时,只需遍历数组并调用join()
每个成员。
Thread current;
for (int i = 0; i < argSize; i++){
current = myThreads[i];
current.join();
}
This joins each thread in turn. The other threads will (possibly, depending on the scheduler) still run in parallel while this happens, if they are still running at the time.
这依次加入每个线程。其他线程将(可能,取决于调度程序)在发生这种情况时仍然并行运行,如果它们当时仍在运行。