`
113.com
  • 浏览: 80492 次
  • 来自: 广州
社区版块
存档分类
最新评论

主线程里创建N个子线程,等待N个子线程全部执行完

    博客分类:
  • java
阅读更多
1.主线程里创建N个子线程,等待N个子线程全部执行完后,打印每个子线程执行的时间。

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 主线程里创建N个子线程,等待N个子线程全部执行完后,打印每个子线程执行的时间。
 * 一种可行的方法
 */
public class MainThread {
	
	public static void main(String[] args) throws InterruptedException {
		int threadNum = 5;
		CountDownLatch latch = new CountDownLatch(threadNum);
		Map<String, Long> map = new ConcurrentHashMap<String, Long>(threadNum);
		ExecutorService pool = Executors.newFixedThreadPool(threadNum);
		for (int i=0; i < threadNum; i++) {
			pool.submit(new SubThread(latch, map));
		}
		latch.await(); //计数减到0时一直等待
		
		for (Map.Entry<String, Long> entry : map.entrySet()) {
			System.out.println(entry.getKey() + "执行耗时:" + entry.getValue() + "毫秒");
		}
		
		pool.shutdown(); // Disable new tasks from being submitted
		try {
		     // Wait a while for existing tasks to terminate
		     if (!pool.awaitTermination(1, TimeUnit.SECONDS)) {
		    	 pool.shutdownNow(); // Cancel currently executing tasks
		    	 // Wait a while for tasks to respond to being cancelled
		    	 if (!pool.awaitTermination(1, TimeUnit.SECONDS)) {
		    		 System.err.println("Pool did not terminate");
		    	 }
		     }
		} catch (InterruptedException ie) {
			// (Re-)Cancel if current thread also interrupted
		    pool.shutdownNow();
		    // Preserve interrupt status
		    Thread.currentThread().interrupt();
		}
	}
	
}

class SubThread implements Runnable {
	private CountDownLatch latch;
	private Map<String, Long> map;
	
	public SubThread(CountDownLatch latch, Map<String, Long> map) {
		this.latch = latch;
		this.map = map;
	}
	
	@Override
	public void run() {
		long start = System.currentTimeMillis();
		System.out.println(Thread.currentThread() + "开始执行...");
		try {
			Thread.sleep(1000); //模拟执行操作
			latch.countDown();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		long end = System.currentTimeMillis();
		System.out.println(Thread.currentThread() + "执行完毕");
		map.put(Thread.currentThread().toString(), end-start);
	}
	
}

 

分享到:
评论

相关推荐

    Java简单实现“主线程等待所有子线程完成再继续”

    有时我们可能需要设计程序,使得主线程在执行过程中能够等待所有子线程完成后再继续执行。这种需求常见于需要同步多个并行任务或者在主任务结束前确保所有子任务已经处理完毕的场景。本文将详细解释如何使用Java实现...

    创建一个带三个子线程的程序,第一个线程启动10ms后

    创建一个带三个子线程的程序,第一个线程启动10ms后,第二个线程再启动,然后再等待10ms后第三个线程启动,每一个线程从1—1000循环输出线程的名称和计数,当三个线程结束时要输出各自的结束信息,然后主线程结束。

    python爬虫-08-主线程会等待子线程执行结束再结束.ev4.rar

    例如,可以创建多个子线程分别负责下载不同的URL,主线程则负责协调各个子线程,确保所有下载任务完成后才结束程序。 在处理大量请求时,为了避免同时发起过多请求导致IP被封禁,可以使用线程池(`...

    线程中创建子线程

    标题中的"线程中创建子线程"是指在主线程或者其他已存在的线程内,通过编程手段创建新的子线程来执行特定的任务。这种方式通常用于执行一些异步操作,如网络请求、文件读写、计算密集型任务等,以避免阻塞主线程,...

    多线程计数实现多线程执行后再执行主线程

    本文将深入探讨如何利用`CountDownLatch`机制来确保多个子线程完成各自的任务后,再让主线程继续执行的方法。这种方法在项目开发中非常实用,尤其是在需要等待多个异步操作完成后才能进行下一步处理的情况下。 ####...

    c++与Qt实现把定时器放进子线程中运行

    它展示了如何创建一个子线程,将QTimer移动到子线程,并确保定时器触发的槽函数也在同一子线程内执行。这有助于保持主线程的轻量级,提高应用程序的响应性。 需要注意的是,跨线程通信在Qt中是通过信号和槽机制来...

    qt编程_在子线程中更新UI界面

    3. **QThread的使用**:要创建一个子线程,首先需要继承QThread并重写run()方法,这里放入耗时操作。然后实例化并启动线程。但是,直接在QThread对象中执行UI操作是错误的,因为QThread本身并不处理GUI事件。 4. **...

    Windows线程的创建与撤销

    实验结果表明,使用 CreateThread() 函数可以创建一个子线程,并使其与主线程分离。使用 Sleep() 函数可以挂起主线程,以便观察子线程的运行情况。使用 ExitThread() 函数可以撤销子线程,并使其退出。 四、实验...

    进程和线程的创建 _实验报告.doc

    创建一个线程并使其立即与主线程并发执行。新创建的线程与主线程均不断地循环,并输出shared_var 的值。主线程在循环中不断地对shared_var 进行加1操作,即每次循环shared_var 被加1;而新创建的线程则不断地对...

    C#创建子线程

    创建一个带有3个子线程的程序,第1个线程启动10ms后,第2个线程再启动,然后等候10ms后第3个线程启动,每一个线程从1~100循环输出线程的名称和计数,当3个线程结束时输出各自的结束信息,然后主线程结束。

    易语言两种多线程使用方式演示

    例如,我们可以定义一个名为“子线程_1”的函数,然后在主线程中调用“创建线程”命令,传入这个函数的地址作为参数,从而启动新的线程。这样,主线程和子线程_1就可以同时执行不同的任务,提高程序并行处理能力。 ...

    MFC用户界面线程的创建示例

    主线程通常是用户界面线程,负责创建和管理窗口;而辅助线程可以执行非UI任务,如文件操作。为了在辅助线程中更新UI,必须使用消息队列和消息泵,因为MFC的UI更新机制依赖于主线程。 创建用户界面线程通常涉及到...

    vs2015+QT5Qt GUI程序主窗体与子线程QThread通信实例

    接下来,我们来创建一个子线程。在QT中,我们不能直接在QThread类的实例上调用start()方法,因为这会导致错误的线程执行。正确的方法是创建一个继承自QThread的类,并重写run()方法。在这个run()方法中,我们将放置...

    易语言线程返回数据的方法

    在易语言中,线程可以用来执行一些耗时但不阻塞主线程的操作,如网络通信、大数据计算等。创建线程可以使程序运行更加流畅,提高用户体验。 二、线程的创建与启动 在易语言中,创建线程通常需要定义一个子程序作为...

    多线程例子 演示多线程使用

    `std::thread::join()`方法用于等待线程结束,防止主线程过早结束导致子线程被异常终止。 7. **线程局部存储**:如果需要每个线程拥有独立的数据,可以使用`std::thread_local`关键字。这样,每个线程都有自己的一...

    深入浅出Java多线程.doc

    在主线程中调用某个子线程的`join()`方法,主线程会等待该子线程执行完成后再继续执行。这样可以确保子线程的操作在主线程的某些操作之前完成,从而满足特定的程序逻辑需求。 在上述代码示例中,`JoinTest`类创建了...

    Labview2015多线程异步调用工程

    合理分配任务给各个子线程,可以使系统资源得到充分利用,减少等待时间,提升整体响应速度。 六、注意事项 在实际应用中,需要关注线程安全、内存管理以及资源竞争等问题。此外,过多的线程会增加系统的管理开销,...

    Java多线程实现异步调用实例

    在描述中提到的`main`方法就是主线程的起点,它会创建并启动A、B、C这三个子线程。 异步调用是在多线程环境中实现的,其中一个线程(通常是主线程)发起一个请求,然后立即返回,无需等待该请求的结果。这使得调用...

    易语言类中启动线程

    在易语言类中启动线程,意味着在类的一个实例中创建一个新的执行流,这个执行流独立于创建它的主线程和其他线程,可以并行执行特定的任务。 3. 易语言线程创建: 易语言提供了“创建线程”命令来创建新的线程。通常...

    易语言多线程传递自定义数据(免加延时方法)

    创建线程时,通常会有一个主线程(默认运行的程序)和若干个子线程。子线程可以并行执行,与主线程相互独立,执行不同的任务。在创建子线程时,我们可能需要向其传递一些自定义的数据,以便在线程中使用这些数据来...

Global site tag (gtag.js) - Google Analytics