基础线程机制--Executor线程池框架

基础线程机制

Executor线程池框架

1.引入Executor的原因

(1)new Thread()的缺点

​  每次new Thread()耗费性能

​  调用new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的创建,之间相互竞争,导致过多的系统资源被占用导致系统瘫痪,不利于定时执行,定期执行,线程中断

(2)采用线程池的优点

​  可以重用创建的线程减少对象的创建,消亡的开销,性能更佳。

​  可以有效的控制最大并发线程数提高系统资源的利用率避免过多的资源竞争,避免堵塞

​  提供定时执行定期执行单线程并发控制等功能。

2.Executor的介绍

​  Executor 在java.util.cocurrent包下,通过该框架来控制线程的启动,执行和关闭,可以简化并发编程的操作。

​  在Java5之后通过Executor来启动线程比使用Thread的start()方法要好,除了更容易管理,还有关键的一点:有助于避免this逃逸的问题--如果我们在构造器中启动一个线程,因为另一个任务可能会在构造器结束之前执行,此时可能回访问到初始化了一半的对象用Executor在构造器中。

​  Executor 框架包括:线程池ExecutorExecutors,ExcutorService,CompletionService,Futrue,Callable 等。

3.Executors方法介绍

Executors类提供四种线程池,

​  newFixedThreadPool,newCachedThreadPoll,newSingleThreadExecutor,newScheduledThreadPool。

1.public static ExecutorService newFixedThreadPoll(int nThreads)

​  创建固定大小的线程池。

2.public static ExecutorSurvice newCachedThreadPoll()

​  创建一个可以缓存的线程池,调用execute将重用以前构造的线程(如果线程可用),如果线程没有可用的,那么将创建一个线程并添加到池中。终止并从缓存中移除那些已经60秒未使用的线程。

3.public static ExecutorService newSingleThreadExecutor()

​  创建一个单线程化的Executor。

4.public static ExecutorService newScheduledThreadPool()

​  创建一个定时及周期性的任务执行的线程池,多数情况下可以来代替Timer类。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoll{
    public static void main(String[]args){
        ExecutorService executorService=Executors.newFixedThreadPool(5);
        for(int i=0;i<10;i++){
            executorService.execute(new MyRunnable());
        }
        executorService.shutdown();

    }
}
class MyRunnable implements Runnable{
    public void run(){
        try {
            System.out.println(Thread.currentThread().getName());
        } catch (Exception e) {
            //TODO: handle exception
        }
    }
}

4.ExecutorService

​  ExecutorService是一个接口,ExecutorService继承了Executor接口,定义了一些生命周期方法。ExecutorSerive的生命周期包括三种状态:运行,关闭,终止。创建后就进入了运行的状态,当调用shutdown()方法时,便进入了关闭状态,此时意味着ExecutorService不在接受任务。但是它还在执行已经提交的任务,等到所有的任务都完成时,便达到终止状态。

public interface ExecutorService extends Executor{
    void shutdown(); //顺次的关闭ExecutorService,不在接受新的任务,等待所有的认为执行完毕,关闭                          ExecutorService。
    boolean isshutdown(); //判断线程池是否已经关闭
    List<Runnable>shutdownNow(); //阻止等待任务启动,并试图关闭当前正在执行的任务,停止接受新的任                                      务,返回处于等待的任务列表。
    boolean isTerminated(); //如果关闭后所有的任务都完成,返回true
    <T>Future<T>submit(Callable<T>task); //提交一个返回值的任务用于执行,返回一个表示任务的未决结果的Futrue,该Future的get方法在成功完成时,将返回该任务的结果。
    <T>Future<T>submit(Runnable tast,T result); //提交一个Runnable任务用于执行,并返回一个该任务的Future,该Future的get方法在成功完成时,将会返回给定的结果。
    
}

5.自定义线程池

用ThreadPoolExecutor类来自定义线程池

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.java.util.concurrent.*;
public class MakeThreadPoll{
    public static void main(String[]args){
        //创建阻塞队列
        BlockingQueue<Runnable>bqueue=new ArrayBlockingQueue<Runnable>(20);
        ThreadPoolExecutor pool=new ThreadPoolExecutor(3, 5, 30, TimeUnit.MICROSECONDS, bqueue);
        Runnable t1=new MyRunnable();
        Runnable t2=new MyRunnable();
        Runnable t3=new MyRunnable();
        Runnable t4=new MyRunnable();
        Runnable t5=new MyRunnable();
        Runnable t6=new MyRunnable();
        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);
        pool.execute(t5);
        pool.execute(t6);
        pool.execute(t1);
        //关闭线程池
        pool.shutdown();

    }
}
class MyRunnable implements Runnable{
    @Override
    public void run(){
        System.out.println(Thread.currentThread().getName()+"正在执行");
        try {
            Thread.sleep(100);
        } catch (Exception e) {
          e.printStackTrace();  //TODO: handle exception
        }
    }
}
上一篇:关机还是不关机?在ExecutorService(Java8)中


下一篇:java – 如何覆盖executorService shutdown方法