背景:实际开发中经常会出现当前线程必须等待子线程执行完毕以后的场景。写了一个简单的例子,使用了BlockingQueue的特性来实现。后面可以优化成按当前线程ID进行控制
使用方法:
public static void main(String[] args) {
TaskManager manager = TaskManager.getInstance(4);
//新建一批线程任务执行
for(int i = 0; i < 100; i++){
manager.doTask(new Runnable(){
public void run() {
System.out.println("------------> " + System.currentTimeMillis());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
});
}
//等待所有子线程执行完毕
manager.waitAllThreadFinsh();
System.out.println("Finish");
}
package task;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public final class TaskManager {
private static TaskManager instance;
private ThreadPoolExecutor pool;
private TaskSupport taskSupport;
private TaskManager(int poolSize){
if(poolSize == 0){
poolSize = Integer.parseInt(System.getenv("NUMBER_OF_PROCESSORS"));
}
taskSupport = new TaskSupport(poolSize);
pool = new ThreadPoolExecutor(poolSize, poolSize, 1000L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
/**
* 外部执行入口
* @param task
*/
public void doTask(final Runnable task){
if(taskSupport.waitNotFull()){
pool.execute(new Runnable(){
public void run() {
try{
task.run();
}
finally{
taskSupport.removeQueue();
}
}
});
}
}
public void waitAllThreadFinsh(){
taskSupport.waitAllThreadFinsh();
}
public static synchronized TaskManager getInstance(int cpuCount){
if(instance == null){
instance = new TaskManager(cpuCount);
}
return instance;
}
}
package task;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
class TaskSupport {
BlockingQueue<Object> supportQueue;
public TaskSupport(int poolSize) {
supportQueue = new ArrayBlockingQueue<Object>(poolSize);
}
/**
* 等待队列有可用空间,之前一直等待。
*/
public boolean waitNotFull() {
try {
while(!supportQueue.offer(new Object(), 1, TimeUnit.SECONDS)){
}
} catch (InterruptedException e) {
return false;
}
return true;
}
/**
* 当前线程等待子线程执行完成
*/
public void waitAllThreadFinsh(){
while(supportQueue.size() > 0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
}
public void removeQueue(){
supportQueue.poll();
}
}
分享到:
相关推荐
`Thread.join()`方法允许主线程等待一个特定的子线程执行完成。一旦调用了`join()`,主线程会被阻塞,直到被调用的线程执行完毕。例如: ```java Thread childThread = new Thread(() -> { // 子线程的代码 }); ...
总结来说,通过合理的线程同步和通信机制,我们可以在多线程环境下确保主程序在所有子线程执行完毕后再继续执行,并获取每个子线程的返回结果。这有助于优化程序性能,避免数据不一致,提升整体的并发处理能力。在...
在C#编程中,多线程是常见的并发执行方式,其中主线程通常负责应用程序的主逻辑,而子线程则可以执行一些独立的任务。当子线程完成其工作后,有时需要通知主线程以便进行下一步操作。本文将详细介绍如何在C#中实现...
然而,如何确保主线程在所有子线程执行完毕后再进行后续操作,成为一个挑战。 首先,我们看到代码中创建了多个线程并发执行任务。每个线程由一个Runnable对象表示,这些Runnable对象在run()方法中执行实际的数据...
当一个程序包含多个执行路径,即线程,有时我们需要确保某个线程执行完毕后再进行下一步操作,这就涉及到“等待线程结束”的功能。本篇文章将详细探讨如何在C++中实现这一功能。 首先,C++11引入了对线程支持的标准...
所以,这种情况实际上是因为进程运行完毕退出导致所有的线程也都跟着退出了,并非是因为主线程的退出导致子线程也退出。 最后,让我们来讨论一下Linux线程模型。在POSIX线程模型中,并没有主线程和子线程之分,所有...
而`join()`方法用于等待线程完成,确保主线程不会在子线程执行完毕之前继续执行。 2. **异常处理**: - 当子线程中发生异常时,`try-except`块可以用来捕获并处理这些异常。但是,`start()`方法在新栈中执行子线程...
当创建了一个线程后,有时我们需要等待这个线程执行完毕后再进行其他操作,这通常被称为线程同步。本资源提供了一种方法,教您如何在VC++中实现等待一个已有线程自动结束的功能。以下是关于这一主题的详细解释。 1....
总结起来,"mfc线程简单例子"可能是一个演示如何在MFC应用中创建线程并在后台执行任务,同时通过进度条控件实时显示任务进度的例子。通过理解和实践这个例子,开发者可以学习到MFC中多线程编程的基本技巧以及如何...
Java线程中的`join()`方法是一个非常重要的同步工具,它允许一个线程(通常为主线程)等待另一个线程(子线程)执行完成后再继续执行。`join()`方法定义在`java.lang.Thread`类中,它使得多线程间的协作更加有序。 ...
下面是一个简单的示例,展示了如何在易语言中创建一个线程并在主线程中判断其是否结束: ```易语言 .线程ID = 创建线程(“线程函数名”, 参数列表) .线程状态 = 线程.状态(.线程ID) .线程未结束: 如果 .线程状态 ...
`myThread.join()`使得主线程等待`workerFunction`执行完毕后再继续运行,避免了主线程提前结束导致子线程被异常终止。 Boost线程库还提供了丰富的同步机制。例如,互斥量(mutex)用于保护共享资源不被并发访问,`...
如果需要在主线程中等待某个线程结束,可以使用`WaitForSingleObject`。此外,确保在适当的时候释放任何由线程创建的资源。 在`t1.exe`文件中,是编译后的可执行程序,它将运行`t1.c`中的代码,演示了如何在Windows...
例如,某些耗时的文件操作或网络通信可以放在子线程中异步执行,这样主线程就可以继续处理其他任务,而不必等待这些操作完成。 在CVI中,创建线程通常涉及使用Windows API函数,如CreateThread或_beginthreadex。...
当主线程等待其他线程完成时,可以使用`WaitForSingleObject`或`WaitForMultipleObjects`函数。在`<thread>`库中,线程对象可以被joinable或detachable,前者需要调用`join`确保线程执行完毕,后者则在对象析构时...
System.out.println("主线程没有找到thread1, thread1已顺利执行完毕!"); } ``` 以上是Java多线程经典示例中所包含的关键知识点。通过这些知识点的学习,可以更好地理解和掌握Java多线程的基本原理和使用方法。
在这个例子中,我们创建了一个`TCheckThreadStatusThread`线程,它会检查指定线程是否正在运行。当按钮被点击时,我们会创建这个线程并等待线程A开始运行。 6. **注意事项** 当判断线程状态时,需要注意线程竞争...
在多线程环境中,我们可以使用委托将UI更新的方法传递给后台线程,然后在后台线程执行完毕后安全地回调到主线程来更新UI。 以下是一个简单的示例: ```csharp using System; using System.Windows.Forms; using ...
5秒后,线程中的`ShowMessage`会弹出一个消息框,显示“线程执行完毕”。 注意,线程安全和同步是多线程编程中必须考虑的问题。在访问共享资源或界面组件时,应使用如`Synchronize`或`Queue`方法确保在主线程中执行...