`

用线程池执行任务

阅读更多
如果你开发项目的时候用到很多的short-lived任务,这里推荐使用“线程池”这项技术。你可以创建一个线程池来执行池中的的任务,来取代每次执行任务是都要为新的任务来new和discard。如果一个线程在池中是可用状态,那么任务将立即执行。执行完成之后线程返回池中,否则,任务将一直等待直到有线程处在可用状态。
   
    J2SE 5.0为大家提供了一个新的java.util.concurrent package,并且在这个报中提供了一个pre-built 的线程池架构。在java.util.concurrent中提供了一个Executor 接口,里面有一个execute的方法,参数是Runnable 类型
   public interface Executor {
     public void execute(Runnable command);
   }


   使用线程池架构,你就必须创建一个Executor实例,然后你给他分配一些runnable任务,例如:
   Executor executor = ...;
   executor.execute(aRunnable1);
   executor.execute(aRunnable2);


    然后你创建或者找到Executor的实现类,实现类可以立即(或者连续)执行分配的任务,例如:
   class MyExecutor implements Executor {
       public void execute(Runnable r) {
           new Thread(r).start();
       }
   }

    concurrency utilities也包括了一个ThreadPoolExecutor类,它提供了很多对线程的一般性操作,提供了四个构造函数,每个都可以指定如:线程池大小,持续时间,一个线程factory,和拒绝线程的handler。
   public ThreadPoolExecutor(int corePoolSize,
                             int maximumPoolSize,
                             long keepAliveTime,
                             TimeUnit unit,
                             BlockingQueue<Runnable> workQueue)
   public ThreadPoolExecutor(int corePoolSize,
                             int maximumPoolSize,
                             long keepAliveTime,
                             TimeUnit unit,
                             BlockingQueue<Runnable> workQueue,
                             ThreadFactory threadFactory)
   public ThreadPoolExecutor(int corePoolSize,
                             int maximumPoolSize,
                             long keepAliveTime,
                             TimeUnit unit,
                             BlockingQueue<Runnable> workQueue,
                             RejectedExecutionHandler handler)
   public ThreadPoolExecutor(int corePoolSize,
                             int maximumPoolSize,
                             long keepAliveTime,
                             TimeUnit unit,
                             BlockingQueue<Runnable> workQueue,
                             ThreadFactory threadFactory,
                             RejectedExecutionHandler handler)

     但是你不必声明构造函数,Executors类会为你创建一个线程池。在一种最简单的情况下,你在Executors类中声明了newFixedThreadPool方法,并且在池中分配了许多线程。你可以使用ExecutorService(继承Executor的一个接口),去execute和submit 那些Runnable任务,使用ExecutorService中的submit方法可以得到一个返回结果,当然submit也可以返回一个Future对象用来检查任务是否执行。

      让我们来先做一个Runnable类,名字为NamePrinter,它通知你运行、暂停、和耗费的时间。
   public class NamePrinter implements Runnable {
     private final String name;
     private final int delay;
     public NamePrinter(String name, int delay) {
       this.name = name;
       this.delay = delay;
     }
     public void run() {
       System.out.println("Starting: " + name);
       try {
         Thread.sleep(delay);
       } catch (InterruptedException ignored) {
       }
       System.out.println("Done with: " + name);
     }
   }


    然后下面是我们测试的项目UsePool,它创建一个有三个线程的线程池,分配了10个任务给它(运行10次NamePrinter),UsePool在被shutdown 和 awaitTermination之前将等待并执行分配的任务。一个ExecutorService必须要在terminated之前执行shutdown,shutdownNow方法是立即尝试shutdown操作。shutdownNow 方法将返回没有被执行的任务。

   import java.util.concurrent.*;
   import java.util.Random;
   
   
   public class UsePool {
     public static void main(String args[]) {
       Random random = new Random();
       ExecutorService executor = 
               Executors.newFixedThreadPool(3);
       // Sum up wait times to know when to shutdown
       int waitTime = 500;
       for (int i=0; i<10; i++) {
         String name = "NamePrinter " + i;
         int time = random.nextInt(1000);
         waitTime += time;
         Runnable runner = new NamePrinter(name, time);
         System.out.println("Adding: " + name + " / " + time);
         executor.execute(runner);
       }
       try {
         Thread.sleep(waitTime);
         executor.shutdown();
         executor.awaitTermination
                 (waitTime, TimeUnit.MILLISECONDS);
       } catch (InterruptedException ignored) {
       }
       System.exit(0);
     }
    }


    输出的结果是:
   Adding: NamePrinter 0 / 30
   Adding: NamePrinter 1 / 727
   Adding: NamePrinter 2 / 980
   Starting: NamePrinter 0
   Starting: NamePrinter 1
   Starting: NamePrinter 2
   Adding: NamePrinter 3 / 409
   Adding: NamePrinter 4 / 49
   Adding: NamePrinter 5 / 802
   Adding: NamePrinter 6 / 211
   Adding: NamePrinter 7 / 459
   Adding: NamePrinter 8 / 994
   Adding: NamePrinter 9 / 459  
   Done with: NamePrinter 0
   Starting: NamePrinter 3
   Done with: NamePrinter 3
   Starting: NamePrinter 4
   Done with: NamePrinter 4
   Starting: NamePrinter 5
   Done with: NamePrinter 1
   Starting: NamePrinter 6
   Done with: NamePrinter 6
   Starting: NamePrinter 7
   Done with: NamePrinter 2
   Starting: NamePrinter 8
   Done with: NamePrinter 5
   Starting: NamePrinter 9
   Done with: NamePrinter 7
   Done with: NamePrinter 9
   Done with: NamePrinter 8

   注意前三个NamePrinter对象启动的非查的快,之后的NamePrinter对象每次启动都要等待前面的执行完成。

    在J2SE 5.0有非常多的pooling framework可以用,例如,你可以创建一个scheduled线程池……
    更多信息还是看官方的concurrency utilities,地址:http://java.sun.com/j2se/1.5.0/docs/guide/concurrency/
分享到:
评论

相关推荐

    Android中的线程池与任务队列

    1. 工作线程(Worker Threads):线程池中的线程,负责执行任务。 2. 任务队列(Task Queue):存储待执行任务的队列,当工作线程空闲时,会从队列中取出任务执行。 3. 拒绝策略(Rejection Policy):当任务队列满...

    Java线程池使用说明

    2. newFixedThreadPool(int nThreads):创建一个固定大小的线程池,池中维护着指定数量的工作线程,一旦工作线程因执行任务结束,将立即补充新的工作线程。 3. newCachedThreadPool():创建一个可缓存的线程池,...

    Django异步任务线程池实现原理

    在Django中,使用线程池的目的不仅仅是为了异步执行任务,还需要能够对这些异步任务进行有效的管理和监控。通过返回一个“期程”(future)对象,可以跟踪任务的执行状态,了解任务是否仍在执行中。此外,全局线程池...

    带任务描述及执行时间的线程池执行简易框架

    带任务描述及执行时间的线程池执行框架, 使用Java 编写, 可以方便地完成多线程任务

    自定义实现Java线程池1-模拟jdk线程池执行流程1

    1. **初始化线程执行任务**:如果当前工作线程数小于核心线程数,会立即创建新的线程执行任务。 2. **任务入队**:如果工作线程数达到或超过核心线程数,任务会被放入工作队列等待执行。这里使用`offer()`方法尝试...

    C++ 线程池+任务池

    线程池是一种资源管理策略,它预先创建一组线程,待有任务需要执行时,从池中取出一个线程来执行任务,完成后线程并不销毁,而是返回线程池等待下一次任务。这种机制避免了频繁地创建和销毁线程带来的开销,提高了...

    Qt实现线程池开发实例

    **使用线程池执行任务** 创建好任务类后,我们可以将其添加到线程池并启动: ```cpp MyTask* task = new MyTask(); QThreadPool::globalInstance()-&gt;start(task); ``` **QTcpSocket用于网络通信** 在上述线程池...

    任务线程池

    任务线程池是一种高效利用系统资源、管理并发执行任务的机制。在多核或多处理器的系统中,线程池能够显著提升程序的性能和响应时间,避免了频繁创建和销毁线程带来的开销。线程池的核心思想是重用已存在的线程来执行...

    BlockingQueue队列自定义超时时间取消线程池任务

    通过设定线程池大小,可以限制并发执行的任务数量,避免资源过度消耗。 `FutureTask`是线程池处理任务的一种方式,它不仅包含了一个`Runnable`或`Callable`任务,还提供了检查任务是否完成、获取结果、取消任务等...

    线程池、任务、任务组、任务池,定时任务的类库-hy.common.tpool.zip

    ExecutorService是线程池的基本服务接口,ThreadPoolExecutor是其具体实现,用于管理一组可重用的工作线程,而ScheduledThreadPoolExecutor则支持定时及周期性执行任务。 任务(Task)是在线程池中执行的工作单元,...

    spring boot使用自定义配置的线程池执行Async异步任务

    Spring Boot 使用自定义配置的线程池执行 Async 异步任务 在 Spring Boot 中执行异步任务时,默认情况下使用的是默认的线程池,但是,在实际项目中,我们可能需要根据项目的需求来定制自己的线程池。下面将介绍如何...

    简单C++线程池实现

    `_promain.cpp`是主程序文件,展示了如何使用线程池执行任务。它可能包括以下部分: 1. **`main`函数**:创建线程池实例,然后提交一系列任务。任务可以是函数对象(functors)、函数指针或Lambda表达式,只要它们...

    C#线程池 所有线程运行完毕

    1. **ThreadPool.QueueUserWorkItem**:这是C#中使用线程池执行异步任务的主要方法。调用此方法时,传入一个委托(Delegate),线程池会在适当的时候执行该委托代表的方法。 2. **WaitHandle** 和 **...

    Java 判断线程池所有任务是否执行完毕的操作

    线程池是一种高效的并发编程方式,但是在使用线程池时,需要确保所有任务都已经执行完毕,以避免系统资源的浪费。 在本文中,我们将介绍如何使用 Java 判断线程池所有任务是否执行完毕的操作。首先,我们需要创建一...

    java线程池使用后到底要关闭吗

    在代码中,我们创建了一个线程池,然后执行一个打印任务,打印出当前java进程的总线程数。结果显示,在创建到15万个线程时,内存占用百分百后java应用崩溃。说明线程未被回收。 因此,使用完线程池后一定要关闭,...

    JAVA使用线程池查询大批量数据

    线程池是一种多线程处理形式,预先创建了若干个线程,当有任务需要执行时,会从线程池中取出一个线程来执行任务,任务执行完毕后,线程返回线程池中等待新的任务。这种机制避免了频繁创建和销毁线程带来的性能开销,...

    c语言跨平台线程池,任务池库libstpool

    使用libstpool库,开发者首先需要初始化线程池,指定线程数量和任务队列的最大容量。然后,可以创建任务并将其加入到任务队列中,设定任务的优先级。当所有任务完成后,调用相应的函数关闭线程池。 1. 初始化线程池...

    线程池的概念

    使用线程池执行任务: ```java executor.execute(new Runnable() { @Override public void run() { // 任务代码 } }); ``` 线程池的关闭: ```java executor.shutdown(); // 不接受新任务,但已提交的任务会...

    Java中多线程的使用线程池.docx

    - `Main` 类中创建了线程池对象,然后创建`MyThread`实例并提交给线程池执行。由于线程池大小为2,因此最多同时只有2个线程执行任务,其他任务会等待。 通过以上介绍,我们可以看到Java中的线程池是如何工作以及...

    Spring基于线程池的定时任务线挰异常实践

    总结来说,这篇博文探讨了如何在Spring中使用线程池执行定时任务,包括配置线程池、创建定时任务、异常处理和线程安全。同时,提到了Spring MVC在Web开发中的角色,以及它如何与任务调度协同工作。理解和掌握这些...

Global site tag (gtag.js) - Google Analytics