`
fackyou200
  • 浏览: 310788 次
  • 性别: Icon_minigender_1
  • 来自: 山西太原
社区版块
存档分类
最新评论

线程池ExecutorService的submit和execute

 
阅读更多

转:线程池ExecutorServicesubmitexecute

 

Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动、调度、管理线程的一大堆API了。在Java5以后,通过 Executor来启动线程比用Threadstart()更好。在新特征中,可以很容易控制线程的启动、执行和关闭过程,还可以很容易使用线程池的特 性。

 

 

 

一、创建任务

 

 

 

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

 

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

 

 

 

二、执行任务

 

 

 

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

 

 

 

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

 

 

 

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

 

executorService.execute(new TestRunnable());

 

 

 

1、创建ExecutorService

 

通过工具类java.util.concurrent.Executors的静态方法来创建。

 

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

 

 

 

比如,创建一个ExecutorService的实例,ExecutorService实际上是一个线程池的管理工具:

 

        ExecutorService executorService = Executors.newCachedThreadPool();

 

        ExecutorService executorService = Executors.newFixedThreadPool(3);

 

        ExecutorService executorService = Executors.newSingleThreadExecutor();

 

 

 

2、将任务添加到线程去执行

 

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

 

 

 

示例1

 

    @Test

 

    publicvoid testDemo() throws Exception {

 

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

 

       ExecutorService es = Executors.newSingleThreadExecutor();

 

       es.execute(new Runnable() {

 

           @Override

 

           publicvoid run() {

 

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

 

           }

 

       });

 

       es.execute(new Runnable() {

 

           @Override

 

           publicvoid run() {

 

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

 

           }

 

       });

 

       //Thread.sleep(1000 * 60 * 60);

 

    }

 

运行结果如下:两个都会执行,但程序只会使用一个线程来运行。

 

线程启动并运行pool-1-thread-1

 

第二个也运行了pool-1-thread-1

 

 

 

示例2:

 

    @Test

 

    publicvoid testDemo3() throws Exception {

 

       //声明一个线程池

 

       ExecutorService ex = Executors.newCachedThreadPool();

 

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

 

           finalint a = i;

 

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

 

           ex.execute(new Runnable() {

 

              publicvoid run() {

 

                  while(true){

 

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

 

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

 

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

 

                     try{

 

                         Thread.sleep(2000);

 

                     }catch(Exception e){

 

                         e.printStackTrace();

 

                     }

 

                  }

 

              }

 

           });

 

       }

 

       Thread.sleep(1000*60*60);

 

    }
输出的结果如下:从中可以发现,第四个一组输出,即一共创建了四个线程,每次每个线程都会执行输出,但不按顺序:位每一次输出都四个算是一组

 

测试....0>pool-1-thread-1,false

 

测试....3>pool-1-thread-4,false

 

测试....2>pool-1-thread-3,false

 

测试....1>pool-1-thread-2,false

 

测试....0>pool-1-thread-1,false

 

测试....3>pool-1-thread-4,false

 

测试....2>pool-1-thread-3,false

 

测试....1>pool-1-thread-2,false

 

测试....1>pool-1-thread-2,false

 

测试....2>pool-1-thread-3,false

 

测试....3>pool-1-thread-4,false

 

测试....0>pool-1-thread-1,false

 

 

 

示例3:

 

    publicvoid testCall() throws Exception{

 

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

 

       class MyCall implements Callable<String>{

 

           privateintseq;

 

           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("完成....");

    }

分享到:
评论

相关推荐

    线程池的submit和execute的区别.md

    ### 线程池的submit和execute方法的区别详解 #### 一、引言 线程池作为Java并发编程中的一项关键技术,在实现高效并发任务管理方面发挥着重要作用。而在实际开发中,开发者经常会遇到两种用于向线程池提交任务的...

    ExecutorService的execute和submit方法

    `ExecutorService`通过`execute()`和`submit()`这两个方法来提交任务进行执行。理解并熟练运用这两个方法对于优化并发性能至关重要。 `execute()`方法: `execute(Runnable command)`是`ExecutorService`最基础的...

    Java 线程池ExecutorService详解及实例代码

    Java线程池ExecutorService是Java并发编程中非常重要的一个组件,它通过管理和复用线程资源,有效地控制并发任务的执行,从而提高系统的性能和稳定性。本文将详细讲解ExecutorService的原理、使用场景以及如何通过...

    简单谈谈ThreadPoolExecutor线程池之submit方法

    在 Executor 接口中,只定义了 execute 方法,而 submit 方法则是在 ExecutorService 接口中定义的。 ```java public interface ExecutorService extends Executor { ... &lt;T&gt; Future&lt;T&gt; submit(Callable&lt;T&gt; task)...

    Java中Future、FutureTask原理以及与线程池的搭配使用

    例如,对于`ExecutorService es`,执行`submit()`方法时,内部会将`Runnable`或`Callable`包装成`RunnableFuture`实例,如`FutureTask`。`ExecutorService`执行这个`RunnableFuture`,任务完成后,结果可通过`Future...

    ExecutorService线程池

    2. **提交任务**:使用`execute(Runnable task)`方法提交Runnable任务,或者使用`submit(Callable&lt;T&gt; task)`提交Callable任务并获取Future结果。 3. **关闭线程池**:任务执行完毕后,应调用`shutdown()`或`shutdown...

    线程池核心组件源码剖析.docx

    2. **ExecutorService接口**:继承自Executor接口,增加了管理和控制线程池的功能,如`submit()`用于提交任务,`shutdown()`用于关闭线程池,`shutdownNow()`用于尝试停止所有正在执行的任务等。 3. **...

    Executor,Executors,ExecutorService比较.docx

    通常,我们不会直接使用`Executor`,而是使用它的子接口`ExecutorService`,因为`ExecutorService`提供了更多的功能,如任务的提交、管理和关闭线程池。 2. **Executors** `Executors`是`java.util.concurrent`包...

    线程池的实现(JAVA)

    通常,我们会创建一个线程池,然后使用`submit()` 或 `execute()` 方法来提交任务。测试代码可能会包含以下部分: ```java ExecutorService executor = Executors.newFixedThreadPool(5); // 创建一个固定大小的...

    创建Java程序中线程池的详解

    2. 使用 `ExecutorService.execute()` 或 `submit()` 方法提交任务到线程池。 3. 当不再有新任务提交时,调用 `shutdown()` 方法通知线程池停止接收新任务,已提交的任务会继续执行。 4. 要强制停止所有任务,可以...

    线程池简单实现chenjiegui

    此外,线程池还可以通过`execute()`方法提交Runnable任务,或通过`submit()`方法提交Callable任务,并返回Future对象,以便于获取任务执行结果。 在实际应用中,我们还可以使用`Executors`类提供的静态工厂方法快速...

    Android线程池ExcutorService

    通过`ExecutorService`的`execute(Runnable task)`方法提交任务,或者使用`submit(Callable&lt;T&gt; task)`提交返回结果的任务。`Runnable`接口用于无返回值的任务,而`Callable`接口则支持带返回值的任务。 5. **关闭...

    JAVA 写的SOCKET线程池

    5. **线程池的提交任务方式**:使用`execute()`方法提交Runnable任务,或使用`submit()`方法提交Callable任务。 6. **关闭线程池**:使用`shutdown()`或`shutdownNow()`方法优雅地关闭线程池,确保所有已提交的任务...

    JDK线程池和Spring线程池的使用实例解析

    JDK线程池是Java中的一个内置线程池实现,它提供了一个ExecutorService接口,该接口提供了execute、submit、shutdown等方法来管理线程池。JDK线程池可以通过ThreadPoolExecutor类来创建,ThreadPoolExecutor类提供了...

    Java线程池完整代码,已经用于实际的项目中,性能稳定.zip

    线程池通常使用`execute()`方法来提交`Runnable`任务,或者使用`submit()`方法来提交`Callable`任务,后者会返回一个`Future`对象,可以用来获取任务执行的结果或检查任务状态。 线程池的工作流程大致如下: 1. **...

    并发编程之Executor线程池原理与源码解读.pdf

    线程池中重要的方法包括execute()、submit()、shutdown()、shutdownNow()、isTerminated()和isShutdown()等。execute()方法用于执行Runnable任务;submit()方法可以用来提交Callable或Runnable任务,并返回一个...

    java并发编程:Executor、Executors、ExecutorService.docx

    Java并发编程中的Executor、Executors和ExecutorService是Java并发编程框架的重要组成部分,它们为开发者提供了高效管理和控制线程执行的工具。以下是对这些概念的详细解释: 1. Executor: Executor是一个接口,它...

    Java 线程池_动力节点Java学院整理

    - `submit(Runnable task)`:和`execute()`类似,但submit()方法返回一个Future对象,可以通过这个对象获取任务的执行结果。 - `shutdown()`:关闭线程池,不再接受新任务,但会等待正在执行的任务完成。 - `...

    线程池程序-threadGroup

    根据`execute()`或`submit()`方法的使用,任务可能返回结果或不返回结果。 在实际应用中,线程池大小的配置是非常关键的,过大可能导致内存消耗过多,过小则可能导致CPU资源未被充分利用。线程池通过`...

Global site tag (gtag.js) - Google Analytics