简体   繁体   English

如何使主线程等待所有线程完成

[英]How to make the main wait for all threads to complete

I have a program in which I've created 10 threads to run. 我有一个程序,其中创建了10个线程来运行。 I want the main thread to wait until everything has finished before it completes. 我希望主线程能够等到一切都完成之后再完成。 I'm trying to use the .join command but it doesn't seem to be working. 我正在尝试使用.join命令,但它似乎不起作用。 Additionally, I'm trying to display the runtime of all the threads but it isn't working correctly. 另外,我正在尝试显示所有线程的运行时,但是运行不正常。 Below is my code. 下面是我的代码。

//File: CohanThread.java
//Author: Ryan A. Cohan
//Date: August 4, 2016
//Purpose: To create, run, and analyze a thread based program. IOBound runs IO intensive
//operations in the form of printing 1000 times to the console. CPUBound runs CPU
//intensive operations by computing an equation and printing 1000 times.

package cohanthread;

import java.text.*;

public class CohanThread{

    public static void main(String args[]) throws InterruptedException{
        NumberFormat formatter = new DecimalFormat("#0.00000");

        IOBound io1 = new IOBound();
        IOBound io2 = new IOBound();
        IOBound io3 = new IOBound();
        IOBound io4 = new IOBound();
        IOBound io5 = new IOBound();

        CPUBound cpu1 = new CPUBound();
        CPUBound cpu2 = new CPUBound();
        CPUBound cpu3 = new CPUBound();
        CPUBound cpu4 = new CPUBound();
        CPUBound cpu5 = new CPUBound();

        long scheduleStart = System.currentTimeMillis();
        io1.start();
        io2.join();
        io3.join();
        io4.join();
        io5.join();
        cpu1.join();
        cpu2.join();
        cpu3.join();
        cpu4.join();
        cpu5.join();
        long scheduleEnd = System.currentTimeMillis();
        System.out.println("Runtime of all threads: " + formatter.format((scheduleEnd - scheduleStart) / 1000d));
        System.out.println("Processes complete.");
    }
}

class IOBound extends Thread{
    NumberFormat formatter = new DecimalFormat("#0.00000");
    @Override
    public void run(){
        long start = System.currentTimeMillis();
        for(int i = 0; i < 1000; i++){
            System.out.println("Thread number is: " + i);
        }
        long end = System.currentTimeMillis();
        System.out.println("IO Thread runtime: " + formatter.format((end - start) / 1000d));
    }
}

class CPUBound extends Thread{
    NumberFormat formatter = new DecimalFormat("#0.00000");
    @Override
    public void run(){
        String binary = "";
        long start = System.currentTimeMillis();
        for(int i = 0; i < 1000; i++){
            while(i > 0){
                int remainder = i % 2;
                binary = remainder + binary;
                i = i / 2;
            }
            System.out.println("Binary number: " + binary);
            long end = System.currentTimeMillis();
            System.out.println("CPU Thread runtime: " + formatter.format((end - start) / 1000d));
        }
    }
}

Join does not start computation, you must start all threads and use join to wait for completion... 联接不会启动计算,您必须启动所有线程并使用联接来等待完成...

https://docs.oracle.com/javase/tutorial/essential/concurrency/join.html https://docs.oracle.com/javase/tutorial/essential/concurrency/join.html

Use this main.... 使用这个主要...。

public static void main(String args[]) throws InterruptedException{
    NumberFormat formatter = new DecimalFormat("#0.00000");

    IOBound io1 = new IOBound();
    IOBound io2 = new IOBound();
    IOBound io3 = new IOBound();
    IOBound io4 = new IOBound();
    IOBound io5 = new IOBound();

    CPUBound cpu1 = new CPUBound();
    CPUBound cpu2 = new CPUBound();
    CPUBound cpu3 = new CPUBound();
    CPUBound cpu4 = new CPUBound();
    CPUBound cpu5 = new CPUBound();

    long scheduleStart = System.currentTimeMillis();
    io1.start();
    io2.start();
    io3.start();
    io4.start();
    io5.start();
    cpu1.start();
    cpu2.start();
    cpu3.start();
    cpu4.start();
    cpu5.start();


    io1.join();
    io2.join();
    io3.join();
    io4.join();
    io5.join();
    cpu1.join();
    cpu2.join();
    cpu3.join();
    cpu4.join();
    cpu5.join();
    long scheduleEnd = System.currentTimeMillis();
    System.out.println("Runtime of all threads: " + formatter.format((scheduleEnd - scheduleStart) / 1000d));
    System.out.println("Processes complete.");
}

you can use java java.util.concurrent package; 您可以使用java java.util.concurrent包;

public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        List<Future<?>> futureList = new ArrayList<>();
        futureList.add(executor.submit(new IOBound()));
        futureList.add(executor.submit(new IOBound()));
        futureList.add(executor.submit(new IOBound()));
        futureList.add(executor.submit(new IOBound()));
        futureList.add(executor.submit(new IOBound()));

        futureList.add(executor.submit(new CPUBound()));
        futureList.add(executor.submit(new CPUBound()));
        futureList.add(executor.submit(new CPUBound()));
        futureList.add(executor.submit(new CPUBound()));
        futureList.add(executor.submit(new CPUBound()));

        for (Future future:futureList) {
            try {
                //this method will blocking until task finished
                future.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }

ExecutorService is the way to go!! ExecutorService是必经之路!!

You can use the executor service here with list of threads to be executed. 您可以在此处将执行程序服务与要执行的线程列表一起使用。

I have updated the program to use Executor Service. 我已经更新程序以使用执行器服务。

import java.text.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CohanThread{

    public static void main(String args[]) throws InterruptedException{
        NumberFormat formatter = new DecimalFormat("#0.00000");

        ExecutorService es = Executors.newFixedThreadPool(5);
        List<Callable<Object>> threadList = new ArrayList<Callable<Object>>();

        IOBound io1 = new IOBound();
        IOBound io2 = new IOBound();
        IOBound io3 = new IOBound();
        IOBound io4 = new IOBound();
        IOBound io5 = new IOBound();
        threadList.add(Executors.callable(io1));
        threadList.add(Executors.callable(io2));
        threadList.add(Executors.callable(io3));
        threadList.add(Executors.callable(io4));
        threadList.add(Executors.callable(io5));

        CPUBound cpu1 = new CPUBound();
        CPUBound cpu2 = new CPUBound();
        CPUBound cpu3 = new CPUBound();
        CPUBound cpu4 = new CPUBound();
        CPUBound cpu5 = new CPUBound();
        threadList.add(Executors.callable(cpu1));
        threadList.add(Executors.callable(cpu2));
        threadList.add(Executors.callable(cpu3));
        threadList.add(Executors.callable(cpu4));
        threadList.add(Executors.callable(cpu5));

        long scheduleStart = System.currentTimeMillis();
        List<Future<Object>> results = es.invokeAll(threadList);
        long scheduleEnd = System.currentTimeMillis();
        System.out.println("Runtime of all threads: " + formatter.format((scheduleEnd - scheduleStart) / 1000d));
        System.out.println("Processes complete.");
    }
}

class IOBound extends Thread{
    NumberFormat formatter = new DecimalFormat("#0.00000");
    @Override
    public void run(){
        long start = System.currentTimeMillis();
        for(int i = 0; i < 1000; i++){
            System.out.println("Thread number is: " + i);
        }
        long end = System.currentTimeMillis();
        System.out.println("IO Thread runtime: " + formatter.format((end - start) / 1000d));
    }
}

class CPUBound extends Thread{
    NumberFormat formatter = new DecimalFormat("#0.00000");
    @Override
    public void run(){
        String binary = "";
        long start = System.currentTimeMillis();
        for(int i = 0; i < 1000; i++){
            while(i > 0){
                int remainder = i % 2;
                binary = remainder + binary;
                i = i / 2;
            }
            System.out.println("Binary number: " + binary);
            long end = System.currentTimeMillis();
            System.out.println("CPU Thread runtime: " + formatter.format((end - start) / 1000d));
        }
    }
}

Note that the List<Future<Object>> answers = es.invokeAll(threadList); 请注意, List<Future<Object>> answers = es.invokeAll(threadList); will wait untill all the threads have completed execution. 将等到所有线程完成执行。

Hope it helps. 希望能帮助到你。 Happy Coding Cheers! 祝您编码愉快!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM