线程和线程池

什么是线程

线程(thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。

在java中如何创建线程

1.继承Thread类重写run方法

2.实现Runnable接口并实现run方法

3.实现Callable接口并实现call方法

4.使用线程池创建

复制代码
class Thread1 extends Thread {

    @Override

    public void run() {

        super.run();

    }

}

class Thread2 implements Runnable {

    @Override

    public void run() {

        

    }

}

class Thread3 implements Callable {

    @Override

    public Object call() throws Exception {

        return null;

    }

}

public class Test {

    public static void main(String[] args) {

        ExecutorService thread4 = Executors.newSingleThreadExecutor();

    }

}
复制代码

 

四种方式的特点

  1. Thread:没什么好说的, 简单易懂
  2. Runnable:因为java具有单继承多实现的机制,所以可以优先使用这个方法
  3. Callable:这个方式开启线程会有一个返回值,而且调用的时候需要将线程包装成FutureTask任务才能运行新线程
  4. 线程池:使用线程池可以避免因为频繁的创建与销毁线程而带来的性能问题,不过如果线程池使用不当也会带来严重问题

线程池的种类

在java的Executors这个工具类中已经内置了几种已经被配置好的线程池,他们包括以下这几种

复制代码
//单例线程池

ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

//缓存线程池

ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

//固定数量线程池

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);

//计划任务线程池

ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(1);
复制代码

 

不过这几种线程池最终都会调用ThreadPoolExecutor的构造函数,换句话说,这几种线程池其实都是具有不同参数的ThreadPoolExecutor,所以只要我们看懂这个ThreadPoolExecutor,其余的也就可以看懂了

ThreadPoolExecutor参数说明

以下是jdk1.8版本的ThreadPoolExecutor的构造函数及其官方说明

复制代码
public ThreadPoolExecutor(int corePoolSize,

                          int maximumPoolSize,

                          long keepAliveTime,

                          TimeUnit unit,

                          BlockingQueue<Runnable> workQueue,

                          ThreadFactory threadFactory,

                          RejectedExecutionHandler handler)
复制代码

corePoolSize – the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set(池中要保留的线程数,即使它们处于空闲状态,除非设置了allowCoreThreadTimeOut)

maximumPoolSize – the maximum number of threads to allow in the pool(池中允许的最大线程数)

keepAliveTime – when the number of threads is greater than the core, this is the maximum time that excess idle threads will wait for new tasks before terminating.( 当线程数大于核心数时,这是多余空闲线程在终止前等待新任务的最长时间。)

unit – the time unit for the keepAliveTime argument(keepAliveTime参数的时间单位)

workQueue – the queue to use for holding tasks before they are executed. This queue will hold only the Runnable tasks submitted by the execute method.( 用于在执行任务之前保留任务的队列。此队列将只保存execute方法提交的可运行任务。)

threadFactory – the factory to use when the executor creates a new thread

handler – the handler to use when execution is blocked because the thread bounds and queue capacities are reached(执行器创建新线程时使用的工厂

handler–由于达到线程边界和队列容量而阻止执行时要使用的处理程序)

当我们使用线程池的execute()或者submit()执行一个任务时,会直接交给corePoolSize来执行,当提交的任务大于corePoolSize时,将任务添加到workQueue中,等workQueue饱和时,会查看这个线程池的核心数是否已是最大,可是不是最大,就继续创建核心进行任务处理。若核心数已经是maximunPoolSize的大小,并且队列饱和,这时再添加任务时,会使用handler处理请求,默认的handler拒绝策略是AbortPolicy。

线程池的拒绝策略

AbortPolicy

丢弃任务并抛出RejectedExecutionException异常。

DiscardPolicy

丢弃任务,但是不抛出异常。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃。

DiscardOldestPolicy

丢弃队列最前面的任务,然后重新提交被拒绝的任务。

CallerRunsPolicy

由调用线程处理该任务

posted @   dianx  阅读(86)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示