Executor线程池

一、为什么要用线程池?

1)、系统启动一个新线程的成本是比较高的,因为它涉及与操作系统交互。在这种情形下,使用线程池可以很好地提高性能,尤其是当程序中需要创建大量生存期很短的线程时,更应该考虑使用线程池;使用线程池可以降低源消耗。通重复利用已建的线程降低线建和造成的消耗。

2)、使用线程池可有有效地控制系统中并发线程的数量;当系统中包含大量并发线程时,会导致系统性能剧烈下降,甚至导致JVM崩溃,而线程池的最大线程参数可以控制系统中并发线程数;

线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。

如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜。),况且我们还不能控制线程池中线程的开始、挂起、和中止。

二、java8改进的线程池

1、线程池相关的接口和类

1)ExecutorService对象代表一个线程池;程序只要将一个Runnable对象或Callable对象(代表线程任务)提交给线程池,只要线程池中有空闲线程,就会立即执行线程任务;

public interface Executor {
    void execute(Runnable command);
}

public interface ExecutorService extends Executor{
    void shutdown();
    List<Runnable> shutdownNow();
    boolean isShutdown();
    boolean isTerminated();
    boolean awaitTermination(long timeout, TimeUnit unit)
        throws InterruptedException;
    /* Future代表Callable对象的call()方法的返回值 */
    <T> Future<T> submit(Callable<T> task);
    /* result显示指定线程执行结束后的返回值,所以Future对象在run()执行结束后返回result */
    <T> Future<T> submit(Runnable task, T result);
    /*因为Runnable中的run()没有返回值,所Future在run()执行结束后返回null,但可以调有Future.isDone()或isCancelled()来获取Runnable对象的执行状态 */
    Future<?> submit(Runnable task); 
    // ...其他方法
}

public interface ScheduledExecutorService extends ExecutorService {
    /* 指定command任务将在delay延迟后执行 */
    public ScheduledFuture<?> schedule(Runnable command,
                                       long delay, TimeUnit unit);
    public <V> ScheduledFuture<V> schedule(Callable<V> callable,
                                           long delay, TimeUnit unit);
    /* 指定command任务将在delay延迟后执行,而且以设定频率重复执行 */
    public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit);
    public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,
                                                     long initialDelay,
                                                     long delay,
                                                     TimeUnit unit);
}

 

2、四种常用线程池创建方式

1)Executors工具类

java1.5新增了一个Executors工厂类来生产线程池ExecutorService;该工厂类提供的四种常用方法如下:

  • newFixedThreadPool(int nThreads):创建一个可复用的,具有固定线程数的线程池;
  •  newFixedThreadPool(int nThreads, ThreadFactory threadFactory)
  • newSingleThreadExecutor():创建一个只有一个线程的线程池。
  • newSingleThreadExecutor(ThreadFactory threadFactory)
  • newCachedThreadPool():创建一个具有缓存功能的线程池。
  • newCachedThreadPool(ThreadFactory threadFactory)
  • newSingleThreadScheduledExecutor()
  • newSingleThreadScheduledExecutor(ThreadFactory threadFactory)
  • newScheduledThreadPool(int corePoolSize):创建具有指定线程数的线程池,它可以在指定延迟时间后执行。
  • newWorkStealingPool(int parallelism)

2)使用线程池来执行线程任务的步骤

public class ExecutorServiceDemo {

	public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
		/**
		 * 使用线程池来执行线程任务的步骤如下:
		 * 1)调用Executors工厂类方法创建一个线程池对象ExecutorService; 
		 * 2)创建Runnable类或Callable类的实例,作为线程执行任务;
		 * 3)调用ExecutorService.submit()来执行Runnable或Callable类的实例; 
		 * 4)当不想提交任何任务时,调用ExecutorService.shutdown()方法关闭线程池;
		 */
		ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
		Future future = pool.submit(new TaskTest(),"success");
		System.out.println(future.get(10, TimeUnit.SECONDS));
		pool.shutdown();
	}

}

class TaskTest implements Runnable{

	@Override
	public void run() {
		System.out.println("正在执行任务。。。。");
	}
}

 

三、合理配置线程池

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值