java 线程数组?

bzzcjhmw  于 2023-01-16  发布在  Java
关注(0)|答案(3)|浏览(136)

因此,我在理解如何避免线程的顺序执行时遇到了一个问题。我试图创建一个线程数组,并在单独的循环中执行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()调用应该在不同的循环中,但是我如何在不同于最初创建线程的循环中引用线程呢?
我需要在类声明中创建一个线程数组吗?循环是否也应该在里面,并且在main之外?
我很困惑,任何信息将不胜感激。谢谢!

6xfqseft

6xfqseft1#

你不能在你启动线程的循环中执行join(你可以,但是你发现,没有并行性)。为线程创建一个数组,在一个循环中启动它们,然后创建第二个循环来执行join调用。我认为你根本不需要内部的for。

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

68bkxrlz

68bkxrlz2#

我需要在类声明中创建线程数组吗?
你需要一个数组或者其他的集合。没有必要把它放在类声明层--它很可能是局部的:

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();
    }
}
nwlls2ji

nwlls2ji3#

当你在一个线程上调用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();
}

这将依次连接每个线程。在此过程中,其他线程(可能,取决于调度程序)仍将并行运行,如果它们当时仍在运行的话。

相关问题