当前位置:编程学习 > JAVA >>

关于java线程池 Ⅰ

这篇文章主要是翻译了一部分jdk自带线程池的API。本来是不想翻译的,结果发现上周看完以后,过了个端午,玩了三天回来发现有些细节又忘记了。。想来想去,决定还是翻译一遍,英语水平有限。。剩下的你懂的。。

我是这么计划的,从上层接口开始一层一层往下。开始工作:

先发一张这篇打算翻译的接口及类的定义的层级关系

http://bbs.itheima.com/thread-23776-1-1.html?fstgj以前的学习网站,需要的自己看下,可以去这个网站下载,下载视频免费,不需要注册和做什么任务。



 

1.java.util.concurrent.Executor

java.util.concurrent.Executor,一个用于执行Runnable任务的实例接口。这个接口提供了一种将每个任务的提交与每个任务具体如何执行解耦的方式,这其中包括线程的使用与调度的细节等等。一个Executor通常被用于替代哪些显示的创建线程的方法。举个栗子,与其说显示的调用new Thread(new RunnableTask() ).start() 去执行一个堆任务,你还不如入像下面这么做:

Executor executor = anExecutor;
 executor.execute(new RunnableTask1());
 executor.execute(new RunnableTask2());
 ...
上面这么写,每次执行execute方法就创建一个新线程,但是,Executor接口并没有严格的要求任务的执行必须是异步的。举个简单的栗子,一个executor也能让一个提交上来的任务直接在调用executor.execute方法的线程上执行,例如:

class DirectExecutor implements Executor {
     public void execute(Runnable r) {
         r.run();
     }
 }
更普遍的写法是让任务执行在调用executor.execute方法的线程之外的线程上。下面的这个executor就为每一个任务创建一个新线程:

class ThreadPerTaskExecutor implements Executor {
     public void execute(Runnable r) {
         new Thread(r).start();
     }
 }
许多Executor的实现类会附加一些限制类似于如何或者何时调用任务。下面的这个executor展示了一个复合型的executor,其将任务排队并移交给第二个executor执行:


class SerialExecutor implements Executor {
     final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
     final Executor executor;
     Runnable active;

     SerialExecutor(Executor executor) {
         this.executor = executor;
     }

     public synchronized void execute(final Runnable r) {
         tasks.offer(new Runnable() {
             public void run() {
                 try {
                     r.run();
                 } finally {
                     scheduleNext();
                 }
             }
         });
         if (active == null) {
             scheduleNext();
         }
     }

     protected synchronized void scheduleNext() {
         if ((active = tasks.poll()) != null) {
             executor.execute(active);
         }
     }
 }

这个Executor接口的实现为这个包下的ExecutorService,其是一个更加拓展的接口。ThreadPoolExecutor类提供了可扩展的线程池的实现。Executors类为上面说的这些Executors提供了便利的工厂方法。

内存一致性影响:一个调用了Executor.execute方法的线程,其中除了调用Executor.execute方法之外的操作应当那优先于这个runnable对象的执行,这个执行可能处于别的线程中。


2.java.util.concurrent.ExecutorService

ExecutorService是一个Executor,提供了用于关闭自己的方法,还有可以返回Future对象以追寻一个或多个任务的工作流程的方法。

一个ExecutorService是可以被关闭的,这样会导致拒绝任何新的任务。ExecutorService定义了两个不同的方法去关闭自己。一个是shutdown()方法,这个方法允许在调用这个方法之前提交上来的任务执行完毕,随后关闭。另外一个shutdownNow()方法则阻止还在等待的任务启动并且试图去停止正在执行的任务。在ExecutorService关闭的基础上,一个executor将没有可以执行的的任务,没有等待中的任务,没有新的提交上来的任务。一个不使用的ExecutorService应当被关闭,从而允许回收它所占用的资源。

submit()方法拓展了Executor.execute方法,创建并返回了一个Future对象,这个对象可以被用于取消执行或者等待任务完成状态。方法invokeAny和invokeAll提供了最经常使用到的大部分模板代码,如执行一系列的任务并且等待其中一个或者所有的任务完成(如果要重写上诉方法,推荐继承类 ExecutorCompletionService 并重写自定义的上述方法)

Executors类提供了ExecutorService所在包下 ExecutorService 类及子类的工厂方法。

使用示例:

这里是一个有一个线程池用于服务发送来的请求的网络服务的简单设计,这里使用Executors.newFixedThreadPool工厂方法来生成固定个数的线程池:


class NetworkService implements Runnable {
   private final ServerSocket serverSocket;
   private final ExecutorService pool;

   public NetworkService(int port, int poolSize)
       throws IOException {
     serverSocket = new ServerSocket(port);
     pool = Executors.newFixedThreadPool(poolSize);
   }

   public void run() { // run the service
     try {
       for (;;) {
         pool.execute(new Handler(serverSocket.accept()));
       }
     } catch (IOException ex) {
       pool.shutdown();
     }
   }
 }

 class Handler implements Runnable {
   private final Socket socket;
   Handler(Socket socket) { this.socket = socket; }
   public void run() {
     // read and service request on socket
   }
 }

下面的方法分两阶段关闭一个ExecutorService,第一步,调用shutdow方法拒绝提交上来的任务;第二步,如果有必要,则调用shutdowNow方法,取消任何延迟的任务:


void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }

内存一致性影响:一个线程中调用ExecutorService.submit方法之外的任何操作应当优先于这个被提交任务被执行,这些被提交任务的执行应当优先于通过Future.get()返回结果。 Java 线程池 类 多线程 socket --------------------编程问答-------------------- --------------------编程问答-------------------- 在没需求时,看这些东西感觉好晦涩难懂。 --------------------编程问答-------------------- happens-before被弄的不知所云了。。
专业的并发网站
补充:Java ,  Java EE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,