欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java 的ExecutorService

程序员文章站 2022-04-04 09:09:31
...

      早期在Java5以前,我们做多线程程序,一般都用原生的Java的多线程API,比如 new Thread(), start ,wait,notify等 ,如果想实现并行任务,那么一般都是For循环来处理。在java 5以后,Sun公司给我们提供了一个比较好用的框架,那就是ExecutorService。新特征中,可以很容易控制线程的启动、执行和关闭过程,还可以很容易使用线程池的特 性。

 

一、创建一个任务

任务就是一个实现了Runnable接口的类。

创建的时候实run方法即可。

 

二、执行任务

通过java.util.concurrent.ExecutorService接口对象来执行任务,该接口对象通过工具类java.util.concurrent.Executors的静态方法来创建。

 

Executors此包中所定义的 ExecutorExecutorServiceScheduledExecutorServiceThreadFactory Callable 类的工厂和实用方法。

 

ExecutorService提供了管理终止的方法,以及可为跟踪一个或多个异步任务执行状况而生成 Future 的方法。 可以关闭 ExecutorService,这将导致其停止接受新任务。关闭后,执行程序将最后终止,这时没有任务在执行,也没有任务在等待执行,并且无法提交新任 务。

executorService.execute(new TestRunnable());创建ExecutorService

        ExecutorService executorService = Executors.newCachedThreadPool();

        ExecutorService executorService = Executors.newFixedThreadPool(100);

        ExecutorService executorService = Executors.newSingleThreadExecutor();

当将一个任务添加到线程池中的时候,线程池会为每个任务创建一个线程,该线程会在之后的某个时刻自动执行。

 

几个简单的例子

public void test1() throws Exception {

       //单例线程,任意时间(同一时间)池中只能有一个线程

       ExecutorService es = Executors.newSingleThreadExecutor();

       es.execute(new Runnable() {

           @Override

           public void run() {

              System.err.println("线程启动并运行"+Thread.currentThread().getName());

           }

       });

       es.execute(new Runnable() {

           @Override

           public void run() {

              System.err.println("第二个也运行了"+Thread.currentThread().getName());

           }

       });

    }

 两个都会执行,但程序只会使用一个线程来运行

 

public void test2() throws Exception {

       //声明一个线程池

       ExecutorService ex = Executors.newCachedThreadPool();

       for (int i = 0; i < 4; i++) {

           final int a = i;

           //每一次execute方法,都是向池中放入一个对象

           ex.execute(new Runnable() {

              public void run() {

                  while(true){

                     System.err.println("测试...."+a+">"

                            +Thread.currentThread().getName()+","

                            +Thread.currentThread().isDaemon());

                     try{

                         Thread.sleep(2000);

                     }catch(Exception e){

                         e.printStackTrace();

                     }

                  }

              }

           });

       }

    }

 一共创建了四个线程,每次每个线程都会执行输出,但不按顺序

 

public void testCall() throws Exception{

       //声明一个类,可以被调用,类似于线程,但它可以拥有返回值

       class MyCall implements Callable<String>{

           private int seq;

           public MyCall(int seq){

              this.seq=seq;

           }

           //抛出异常并可以拥有返回值

           public String call() throws Exception {

              System.err.println("执行"+seq+","+Thread.currentThread().getName());

              Thread.sleep(3000);

              System.err.println("Weak up "+seq);

              return "完成"+seq;//这是返回值

           }

       }

       ExecutorService es = Executors.newCachedThreadPool();//创建线程池对象

       List<Future<String>> result =new ArrayList<Future<String>>();//放结果用的集合

       for(int i=0;i<3;i++){

           Future<String> f=es.submit(new MyCall(i));//线程执行完成以后可以通过引用获取返回值

           result.add(f);

       }

       for(Future<String> f:result){

           System.err.println("返回值:"+f.get());//输出返回的值

       }

       System.err.println("完成....");

    }

   

    第三个例子主要实现了Callable接口,通过实现这个接口,可以实现线程在执行任务之后有返回值,也可以在这个地方,实现比如多个任务同时执行完成后在进行下一轮,或者其中一个任务执行失败后其他任务停止执行的功能

 for(Future<String> f:result){
           System.err.println("返回值:"+f.get());//输出返回的值
 }

 

 

 

相关标签: executorService