`
菜菜土人
  • 浏览: 12498 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

主线程等待线程池结束

 
阅读更多

http://dongdong1314.blog.51cto.com/389953/224932/


所有SynchronousQueue,它将任务直接提交给线程而不保持它们。在此,如果不存在可用于立即运行任务的线程,则试图把任务加入队列将失败,因此会构造一个新的线程。此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。直接提交通常要求无界 maximumPoolSizes 以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。

  • 无界队列。使用无界队列(例如,不具有预定义容量的ArrayBlockingQueue)有助于防止资源耗尽,但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低 CPU 使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,如果它们是 I/O 边界),则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,CPU 使用率较高,但是可能遇到不可接受的调度开销,这样也会降低吞吐量. Above from Javadoc1.6

    创建线程池,有多种构造函数。如下两种:
    /*public ThreadPoolExecutor(int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime, TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    RejectedExecutionHandler handler)
    */

    ThreadPoolExecutor threadPool =newThreadPoolExecutor(5, 5, 3,
    TimeUnit.SECONDS,newArrayBlockingQueue<Runnable>(100),
    newThreadPoolExecutor.AbortPolicy());

    /*public ThreadPoolExecutor(int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue)*/

    ThreadPoolExecutor threadPool2 =newThreadPoolExecutor(5, 8, 1,
    TimeUnit.SECONDS,newLinkedBlockingQueue<Runnable>());
    使用LinkedBlockingQueue,即不限队列大小,这时maximumPoolSize无效。池中线程数最多为corePoolSize

    下面想要完成这样的功能:
    主线程在线程池中所有线程结束后才继续执行或结束。
    importjava.util.concurrent.LinkedBlockingQueue;
    importjava.util.concurrent.ThreadPoolExecutor;
    importjava.util.concurrent.TimeUnit;


    publicclassTestThreadPool {
    publicstaticvoidmain(String[] args) {

    System.out.println("main thread started!");
    /*public ThreadPoolExecutor(int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue)*/

    ThreadPoolExecutor threadPool2 =newThreadPoolExecutor(5, 8, 1,
    TimeUnit.SECONDS,newLinkedBlockingQueue<Runnable>());
    for(inti = 0; i < 10; i++) {
    threadPool2.execute(newTask(i));
    }
    threadPool2.shutdown();//关闭后不能加入新线程,队列中的线程则依次执行完
    while(threadPool2.getPoolSize()!=0);
    System.out.println("main thread end!");
    }
    }

    classTaskimplementsRunnable{
    intcount;
    Task(inti){
    this.count = i;
    }
    publicvoidrun() {
    try{
    System.out.println("in thread "+count);
    Thread.sleep(10000);
    }catch(InterruptedException e) {
    e.printStackTrace();
    }

    System.out.println("thread "+count+" end!");
    }
    }
    /*
    main thread started!
    in thread 1
    in thread 0
    in thread 2
    in thread 3
    in thread 4
    thread 1 end!
    in thread 5
    thread 3 end!
    in thread 6
    thread 2 end!
    in thread 7
    thread 0 end!
    in thread 8
    thread 4 end!
    in thread 9
    thread 5 end!
    thread 8 end!
    thread 7 end!
    thread 6 end!
    thread 9 end!
    main thread end!
    */
    采用的是getPoolSize()返回当前池中的线程数,程序也说明shutdown虽然关闭线程池操作,但只是不加入新线程,而线程池队列中的线程仍将继续执行完成后,才会最后关闭。因此在池中线程未结束时当前线程数不为0.

    原来使用thread.join(),在不用线程池时很容易使用,join()似乎要在thread.start()后才能有效,而线程池则直接用threadPool.execute(runnable or thread),用join()无效。
    for(inti = 0; i < 10; i++) {
    Thread t =newThread(newTask(i),"thread "+ i);
    threadPool2.execute(newTask(i));
    //t.start();
    try{
    t.join();//never effective
    }catch(InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }
    threadPool2.shutdown();//关闭后不能加入新线程,队列中的线程则依次执行完
    //threadPool2.shutdownNow(); //立即中断停止线程执行,返回等待执行的任务列表
    System.out.println("main thread end!");
    /*
    main thread started!
    in thread 0
    in thread 1
    main thread end!
    in thread 2
    in thread 3
    in thread 4
    thread 1 end!
    in thread 5
    thread 0 end!
    in thread 6
    thread 4 end!
    in thread 7
    thread 3 end!
    in thread 8
    thread 2 end!
    in thread 9
    thread 5 end!
    thread 6 end!
    thread 9 end!
    thread 8 end!
    thread 7 end!
    */

    今天发现threadPoolExecutor.isTerminated()可以代替比较,该函数表示如果关闭后所有任务都已完成,则返回true。另一函数threadPoolExecutor.isTerminating()则表示如果此执行程序处于在shutdownshutdownNow之后正在终止但尚未完全终止的过程中,则返回 true。

  • 分享到:
    评论

    相关推荐

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

      `Thread.join()`方法允许主线程等待一个特定的子线程执行完成。一旦调用了`join()`,主线程会被阻塞,直到被调用的线程执行完毕。例如: ```java Thread childThread = new Thread(() -&gt; { // 子线程的代码 }); ...

      主线程等待子多线程(无结果返回)执行完成再继续执行

      "主线程等待子多线程(无结果返回)执行完成再继续执行"这个主题就涉及到如何在Java、C#、Python等编程语言中实现这种同步机制。下面将详细讨论这个知识点。 **1. Java中的`Thread.join()`方法** 在Java中,主线程...

      JAVA主线程等待子线程执行完毕再执行[参照].pdf

      然后,主线程等待子线程的结束,使用 `join()` 方法来实现。 ```java public class JoinDemo { public static void main(String[] args) throws Exception { // 创建子线程,并启动子线程 Thread subThread = ...

      Java多线程–让主线程等待所有子线程执行完毕

      要解决“让主线程等待所有子线程执行完毕”的问题,可以采用以下策略: 1. 使用`join()`方法:如提到的,直接在每个子线程的`start()`之后调用`t.join()`,会导致所有线程按顺序执行。这是因为`join()`会让主线程...

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

      child.join() # 主线程等待子线程结束 ``` 2. 使用`Event`对象:`threading.Event`提供了一个信号机制,子线程完成任务后设置标志,主线程通过检查这个标志判断是否继续执行。 ```python import threading def ...

      【线程池扫描端口的demo程序C#版VS2010】可以取消,等待扫描结束

      4. 主线程使用`TaskCompletionSource.Task`属性进行等待,直到所有任务完成或被取消。 通过这个C#版的线程池端口扫描demo,开发者可以学习到如何有效地管理线程池任务,实现任务的取消以及等待所有任务完成,这对于...

      C# 线程池使用示例

      // 阻止主线程过早结束 } static void YourMethod(object state) { Console.WriteLine("线程池线程正在执行任务..."); // 这里执行你的任务代码 } } ``` 总结,C#线程池是多线程编程中不可或缺的一部分,它...

      MySQL的线程池原理学习教程

      调度方式方面,MySQL支持三种连接管理策略:No-Threads(主线程处理)、One-Thread-Per-Connection(一对一模式)和Pool-Threads(线程池)。No-Threads主要用于调试,One-Thread-Per-Connection是线程池之前的默认...

      一个linux下的socket线程池实现

      在“一个Linux下的socket线程池实现”项目中,可能的架构设计是这样的:主线程负责监听socket连接,当有新的客户端连接请求到达时,主线程不直接处理,而是将这个任务放入任务队列。线程池中的空闲线程会从任务队列...

      Java多线程--等待所有子线程执行完的五种方法.docx

      `Thread.join()`方法允许主线程等待特定线程结束。例如,如果有多个子线程,我们可以在每个子线程执行`join()`,这样主线程会依次等待每个子线程完成。例如: ```java Thread thread1 = new Thread(...); Thread ...

      包含线程池的boost库

      `thread_pool.wait()`确保所有任务都完成后才结束主线程。 使用预编译好的Boost库,尤其是针对特定版本(这里是1.59版),可以避免自己配置和编译Boost的过程,节省时间和资源。不过,要注意的是,预编译库可能只...

      如何等待一个已有线程自动结束的VC++代码

      主线程可以通过`GetExitCodeThread`获取线程的退出状态。 7. **线程安全**: 在多线程环境中,对共享资源的操作需要特别小心,以防止数据不一致。可以使用互斥量、临界区等同步对象确保同一时刻只有一个线程访问...

      Qt 线程池(QThreadPool )的使用

      但要注意,非UI线程不应直接修改UI组件,应通过信号发送数据,由主线程来更新UI。 总结来说,Qt的线程池和`QtConcurrent`模块为开发者提供了强大而易用的多线程编程工具,能够有效地管理和执行并发任务,提升程序的...

      基于liunx操作系统的线程池项目

      5. 销毁线程池:所有任务完成后,主线程通知所有工作线程退出,然后销毁线程池。 在这个过程中,线程间的同步和通信至关重要。例如,为了防止多个线程同时修改任务队列,我们需要使用互斥锁来保护对队列的访问。...

      linux线程池 条件变量

      5. **线程池的关闭**:当不再有新的任务提交,并且所有现有任务都已完成,主线程会通知所有工作线程停止运行。这通常通过向工作队列添加一个特殊信号或标记来实现,然后使用条件变量唤醒所有等待的线程。线程在接收...

      基于Android的KYStartUp启动优化框架.zip

      主线程与子线程分离区分必须在主线程执行的任务和可以在子线程执行的任务,避免主线程阻塞。 线程池管理使用线程池管理子线程任务,提高线程利用率和执行效率。 3. 启动监听 启动事件监听提供启动监听器,监听...

      最简单的C#线程池创建Demo演示代码

      在.NET框架中,C#语言提供了丰富的多线程...主线程等待所有任务完成后再结束。 理解并熟练掌握线程池的使用是每个C#开发者必备的技能,它有助于优化应用程序的性能,提高系统资源利用率,并简化多线程编程的复杂性。

      Linux下基于socket多线程并发通信的实现

      当服务器接收到新连接时,它在一个单独的线程中处理这个连接,这样主线程可以继续监听新的连接请求。每个客户端的通信都在自己的线程中进行,实现了并发处理。 在多线程编程中,需要注意线程安全问题,比如使用互斥...

      1java锁与并发与线程池.doc

      在示例中,主线程启动线程a,然后等待a结束,接着启动线程b并等待其结束,最后主线程结束。 - **守护线程**(Daemon Threads)与用户线程相对,它们在后台运行,只有当所有非守护线程结束后,JVM才会终止守护线程。...

      Qt 之多线程处理多任务

      例如,以下代码展示了如何在工作线程中执行任务并等待其完成,同时允许主线程继续处理其他事件: ```cpp QThread workerThread; MyTask task; workerThread.start(); // 将任务移动到工作线程 task.moveToThread(&...

    Global site tag (gtag.js) - Google Analytics