线程执行器

这套机制分离了任务的建立和执行。经过使用执行器,仅仅须要实现Runnable接口的对象,而后将这些对象发送给执行器便可。执行器经过建立所需线程,来负责这些Runnable对象的建立,实例化以及运行。可是执行器的功能不限于此,他使用了线程池来提升应用程序的性能。当发送一个任务给执行器时,执行器会尝试使用线程池中的线程来执行这个任务,避免了不断地建立和销毁线程而致使的性能降低。java

  • 建立线程执行器web

使用执行器框架(Executor Framework)第一步是建立ThreadPoolExecutor对象。能够ThreadPoolExecutor类提供的四个构造器或者使用Executors的工厂类来建立ThreadPoolExecutor对象。
缓存

package com.packtpub.java7.concurrency.chapter4.recipe1.task;

import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * This class implements a concurrent task 
 *
 */
public class Task implements Runnable {

    /**
     * The start date of the task
     */
    private Date initDate;
    /**
     * The name of the task
     */
    private String name;
    
    /**
     * Constructor of the class. Initializes the name of the task
     * @param name name asigned to the task
     */
    public Task(String name){
        initDate=new Date();
        this.name=name;
    }
    
    /**
     * This method implements the execution of the task. Waits a random period of time and finish
     */
    @Override
    public void run() {
        System.out.printf("%s: Task %s: Created on: %s\n",Thread.currentThread().getName(),name,initDate);
        System.out.printf("%s: Task %s: Started on: %s\n",Thread.currentThread().getName(),name,new Date());
        
        try {
            Long duration=(long)(Math.random()*10);
            System.out.printf("%s: Task %s: Doing a task during %d seconds\n",Thread.currentThread().getName(),name,duration);
            TimeUnit.SECONDS.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.printf("%s: Task %s: Finished on: %s\n",Thread.currentThread().getName(),name,new Date());
    }

}
package com.packtpub.java7.concurrency.chapter4.recipe1.task;

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * This class simulates a server, for example, a web server, that receives
 * requests and uses a ThreadPoolExecutor to execute those requests
 *
 */
public class Server {
    
    /**
     * ThreadPoolExecutors to manage the execution of the request
     */
    private ThreadPoolExecutor executor;
    
    /**
     * Constructor of the class. Creates the executor object
     */
    public Server(){
        executor=(ThreadPoolExecutor)Executors.newCachedThreadPool();
    }
    
    /**
     * This method is called when a request to the server is made. The 
     * server uses the executor to execute the request that it receives
     * @param task The request made to the server
     */
    public void executeTask(Task task){
        System.out.printf("Server: A new task has arrived\n");
        executor.execute(task);
        System.out.printf("Server: Pool Size: %d\n",executor.getPoolSize());
        System.out.printf("Server: Active Count: %d\n",executor.getActiveCount());
        System.out.printf("Server: Completed Tasks: %d\n",executor.getCompletedTaskCount());
    }

    /**
     * This method shuts down the executor
     */
    public void endServer() {
        executor.shutdown();
    }

}
package com.packtpub.java7.concurrency.chapter4.recipe1.core;

import com.packtpub.java7.concurrency.chapter4.recipe1.task.Server;
import com.packtpub.java7.concurrency.chapter4.recipe1.task.Task;

/**
 * Main class of the example. Creates a server and 100 request of the Task class
 * that sends to the server
 *
 */
public class Main {

    /**
     * Main method of the example
     * @param args
     */
    public static void main(String[] args) {
        // Create the server
        Server server=new Server();
        
        // Send 100 request to the server and finish
        for (int i=0; i<100; i++){
            Task task=new Task("Task "+i);
            server.executeTask(task);
        }
        
        server.endServer();

    }

}

若是须要执行新的任务,缓存线程池就会建立新线程;若是线程所运行的任务执行完成后而且这个线程可用,那么缓存线程池将会重用这些线程。线程的重用的优势是减小了建立新线程所花费的时间。然而,新任务固定会依赖线程来执行,所以缓存线程池也有缺点,若是发送过多的任务给执行器,系统的负荷将会过载。框架

PS:仅当线程的数量是合理的或者线程只会运行很短的时间,合适采用Executors工厂类的newCachedThreadPool()方法来建立执行器。dom

ThreadPoolExecutor类的重要特性是,一般须要显示地去结束他。
ide

相关文章
相关标签/搜索