所以我遇到了解如何避免顺序执行线程的问题。我试图创建一个线程数组并在单独的循环中执行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
}
}
这里是在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();
}
}
}
显然,这不是并行工作的线程示例。他们正在等待彼此完成。我知道join()和start()调用应该在不同的循环中,但是如何在与最初创建的循环不同的循环中引用该线程?
我是否需要在类声明中创建一个线程数组?循环是否应该在那里,在主要的外面?
我很困惑,任何信息都会受到赞赏。谢谢!
答案 0 :(得分:14)
你不能在你启动它们的循环中进行连接(你可以,但是你发现,没有并行性)。为线程创建一个数组,在一个循环中启动它们,然后创建一个执行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
}
我怀疑你想自己这样做,但标准方法是使用Executor,Thread Pools等,请参阅Oracle Tutorials
答案 1 :(得分:3)
我是否需要在类声明中创建一个线程数组?
您需要一个数组或其他一些集合。没有必要把它放在类声明级别 - 它可能很好地是本地的:
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();
}
}
答案 2 :(得分:2)
当你在一个线程上调用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
}
现在,如果要在另一个函数中加入线程,则必须使线程数组成为成员变量。否则,您可以按原样使用。
如果要加入线程,只需遍历数组并在每个成员上调用join()
。
Thread current;
for (int i = 0; i < argSize; i++){
current = myThreads[i];
current.join();
}
依次加入每个线程。其他线程(可能,取决于调度程序)在发生这种情况时仍然并行运行,如果它们仍在运行的话。