当前位置: 首页 > 图灵资讯 > 技术篇> Java5 并发学习

Java5 并发学习

来源:图灵教育
时间:2023-04-28 09:25:22

http://lavasoft.blog.51cto.com/62575/115112/

Java5之后,并发线程发生了根本性的变化,最重要的是很多新的启动、调度和管理线程的API。Java5之后,通过Executor启动线程比使用Threadstart()更好。在新特性中,可以轻松控制线程的启动、执行和关闭过程,也可以轻松使用线程池的特性。

一、创建任务

任务是实现Runnable接口的类别。

创建时,实run方法就可以了。

二、执行任务

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

本包定义的Executors Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类工厂及实用方法。

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

executorService.execute(new TestRunnable());

1、创建Executorservicer

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

本包定义的Executors Executor、ExecutorService、ScheduledExecutorService、ThreadFactory 和 Callable 类工厂及实用方法。

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

ExecutorService executorService = Executors.newCachedThreadPool();

ExecutorService executorService = Executors.newFixedThreadPool(3);

ExecutorService executorService = Executors.newSingleThreadExecutor();

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

当将任务添加到线程池中时,线程池将为每个任务创建一个线程,并在以后的某个时间自动执行。

三、关闭执行服务对象

executorService.shutdown();

四、综合实例

package concurrent;     import java.util.concurrent.ExecutorService;     import java.util.concurrent.Executors;     /**  * Created by IntelliJ IDEA.  *  * @author leizhimin 2008-11-25 14:28:59  */     public     class TestCachedThreadPool {                  public     static     void main(String[] args) {     //                ExecutorService executorService = Executors.newCachedThreadPool();                      ExecutorService executorService = Executors.newFixedThreadPool(5);      //             ExecutorService executorService = Executors.newSingleThreadExecutor();                         for (    int i = 0; i < 5; i++) {                              executorService.execute(    new TestRunnable());                              System.out.println(    "************* a" + i +     " *************");                      }                      executorService.shutdown();              }      }     class TestRunnable     implements Runnable {                  public     void run() {                      System.out.println(Thread.currentThread().getName() +     “调用线程。");                          while (    true) {                                  try {                                      Thread.sleep(5000);                                      System.out.println(Thread.currentThread().getName());                              }     catch (InterruptedException e) {                                      e.printStackTrace();                              }                      }              }      }

运行结果:

************* a0 *************     ************* a1 *************     pool-1-thread-调用2线程。     ************* a2 *************     pool-1-thread-调用3线程。     pool-1-thread-调用1线程。     ************* a3 *************     ************* a4 *************     pool-1-thread-调用4线程。     pool-1-thread-调用5线程。     pool-1-thread-2     pool-1-thread-1     pool-1-thread-3     pool-1-thread-5     pool-1-thread-4     pool-1-thread-2     pool-1-thread-1     pool-1-thread-3     pool-1-thread-5     pool-1-thread-4          ...

五、获取任务执行的返回值

Java5之后,任务分为两类:一类是实现Runnable接口的类,另一类是实现Callable接口的类。两者都可以由ExecutorService执行,但Runnable任务没有返回值,而Callable任务有返回值。而且Callable的call()方法只能通过ExecutorService进行 submit ( Callable <T>task)执行方法,并返回一个 <T> Future <T>,这意味着任务等待完成。 Future。

public interface Callable<V>

返回结果并可能抛出异常任务。实现者定义了一个没有任何参数的电话

CallableRunnable,两者都是为那些实例可能由另一个线程执行的类别设计的。但是Runnable

Executors包含一些从其他普通形式转变为 Callable

callable中的call()方法类似于runnable中的run()方法,即前者有返回值,后者没有。

当将Callable对象传递给Executorservice的submit方法时,call方法将自动在线程上执行,并将执行结果返回到future对象。

同样,如果将Runnable对象传递给Executorservice的Submit方法,Run方法将自动在线程上执行,并将执行结果返回Future对象,但在Future对象上调用get方法将返回null。

不幸的是,在Java 在API文档中,这个介绍非常混乱。估计是翻译还没搞清楚的原因。或者说注释不到位。以下是一个例子:

import java.util.ArrayList;       import java.util.List;       import java.util.concurrent.*;       /**  * Calable接口测试  *  * @author leizhimin 2008-11-26 9:20:13  */       public       class CallableDemo {                      public       static       void main(String[] args) {                        ExecutorService executorService = Executors.newCachedThreadPool();                        List<Future<String>> resultList =       new ArrayList<Future<String>>();                              //创建10个任务并执行                              for (      int i = 0; i < 10; i++) {                                      //使用ExecutorService执行Callable类型的任务,将结果保存在future变量中                                Future<String> future = executorService.submit(      new TaskWithResult(i));                                      ////将任务执行结果存储在List中                                resultList.add(future);                        }                              ///遍历任务结果                              for (Future<String> fs : resultList) {                                      try {                                        System.out.println(fs.get());           ////打印每个线程(任务)执行的结果                                }       catch (InterruptedException e) {                                        e.printStackTrace();                                }       catch (ExecutionException e) {                                        e.printStackTrace();                                }       finally {                                              //启动顺序关闭,执行以前提交的任务,但不接受新任务。若已关闭,则调用无其他作用。                                        executorService.shutdown();                                }                        }                }        }       class TaskWithResult       implements Callable<String> {                      private       int id;                      public TaskWithResult(      int id) {                              this.id = id;                }                      /**           * 任务的具体过程,一旦任务传递给ExecutorServicesubmit方法,该方法将在一个线程上自动执行。           *           * @return           * @throws Exception           */                      public String call()       throws Exception {                        System.out.println(      "call()方法自动调用,干活!!!!             " + Thread.currentThread().getName());                              ////模拟耗时的操作                              for (      int i = 999999; i > 0; i--) ;                              return       "call()方法自动调用,任务的结果是:“ + id +       "    " + Thread.currentThread().getName();                }        }

运行结果:

call()方法自动调用,工作!!!             pool-1-thread-1        call()方法自动调用,工作!!!             pool-1-thread-3        call()方法自动调用,工作!!!             pool-1-thread-4        call()方法自动调用,工作!!!             pool-1-thread-6        call()方法自动调用,工作!!!             pool-1-thread-2        call()方法自动调用,工作!!!             pool-1-thread-5        call()方法自动调用,任务结果为:0    pool-1-thread-1        call()方法自动调用,任务结果如下:1    pool-1-thread-2        call()方法自动调用,干活!!!!             pool-1-thread-2        call()方法自动调用,工作!!!             pool-1-thread-6        call()方法自动调用,工作!!!             pool-1-thread-4        call()方法自动调用,任务结果如下:2    pool-1-thread-3        call()方法自动调用,工作!!!             pool-1-thread-3        call()方法自动调用,任务结果如下:3    pool-1-thread-4        call()方法自动调用,任务结果如下:4    pool-1-thread-5        call()方法自动调用,任务结果如下:5    pool-1-thread-6        call()方法自动调用,任务结果如下:6    pool-1-thread-2        call()方法自动调用,任务结果如下:7    pool-1-thread-6        call()方法自动调用,任务结果如下:8    pool-1-thread-4        call()方法自动调用,任务结果如下:9    pool-1-thread-3        Process finished with exit code 0