博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java线程池
阅读量:5262 次
发布时间:2019-06-14

本文共 3400 字,大约阅读时间需要 11 分钟。

目录

创建线程的方法

- 实现Runnable接口- 实现Callable接口- 继承Thread类

为什么要使用线程池

- 降低资源消耗,减少创建线程的开销- 提高响应速度,新任务可以由空闲线程立刻执行- 可管理性,线程池统一管理

创建线程池的方法

Executors类提供了几个静态方法用于创建线程池

- newSingleThreadExecutor(),核心池大小为1,LinkedBlockingQueue(最大)- newFixedThreadPool(n),指定核心池大小为- newCachedThreadPool(),- newScheduledThreadPool(),定时任务,有多线程实现和单线程实现

不建议使用Executors提供的几种线程池而要使用ThreadPoolExecutor的构造方法指定参数

防止OOM,Executors提供的几种线程池的等待队列没有设置大小限制(最大),可能会造成OOM,所以一般使用ThreadPoolExecutor的构造方法创建线程池:

public class ThreadPoolExecutor extends AbstractExecutorService {    .....    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,            BlockingQueue
workQueue); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue
workQueue,ThreadFactory threadFactory); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue
workQueue,RejectedExecutionHandler handler); public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit, BlockingQueue
workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler); ...}

线程池的参数

- corePoolSize:核心池大小- maximumPoolSize:最大线程数- keepAliveTime:线程的空闲时间- unit:空闲时间的单位(时分秒毫秒)- workQueue:等待队列/阻塞队列,有多种类型- threadFactory:线程工厂,用来创建线程- handler:拒绝策略,多种类型

线程池的状态

running=0shutdown=1stop=2terminated=3

调用ThreadPoolExecutor的shutdown方法后,处于shutdown状态;

调用shutdownNow方法后,处于stop状态
所有工作线程已经销毁并且缓存队列清空,处于terminated状态

任务提交发生了什么

通过ThreadPoolExecutor.execute()方法提交任务,

如果线程数小于核心线程数,则创建线程执行任务;
否则,如果线程数小于最大线程数,则尝试将任务放进等待队列;
如果等待队列已满,并且线程数小于最大线程数,则新建线程执行该任务;
如果已达最大线程数,则采取拒绝策略。

关于keepAliveTime,当核心池已满时,会对核心池线程的空闲时间进行判断并回收,直至线程数不大于核心线程数。

如果还设置了allowCoreThreadTimeOut,那么在线程数小于等于核心线程数的时候也会回收

等待队列的类型

- ArrayBlockingQueue,必须指定大小- LinkedBlockingQueue,默认大小为最大- SynchronousQueue,新建线程执行任务

拒绝策略

- ThreadPoolExecutor.AbortPolicy:丢弃任务,抛出RejectedExecutionException异常- ThreadPoolExecutor.DiscardPolicy:丢弃任务,不抛出异常- ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前端的任务- ThreadPoolExecutor.CallerRunsPolicy:调用者处理该任务

线程池的关闭

- shutdown():不再接受新任务,等待已有任务完成- shutdownNow():不再接受新任务,尝试中断正在执行的任务并清空等待队列(通过调用每个线程的interrupt方法)

合理配置线程池大小

- cpu密集型:cpu+1- IO密集型:2*cpu

线程池使用示例

public class ThreadTest {    public static void main(String[] args) {        ThreadPoolExecutor executor=new ThreadPoolExecutor(                1000,2000,1000, TimeUnit.MILLISECONDS,                new LinkedBlockingQueue<>(1000));        for(int i=0;i<999;i++){            MyTask myTask = new MyTask(i);            executor.execute(myTask);            System.out.println("核心池线程数: "+executor.getCorePoolSize()                    +"等待队列: "+executor.getQueue().size()                    +"已完成任务数"+executor.getCompletedTaskCount());        }        executor.shutdown();    }   }class MyTask implements Runnable{    private int taskNum;    public MyTask(int taskNum) {        this.taskNum = taskNum;    }    @Override    public void run() {        System.out.println("开始task "+taskNum);        try {            Thread.currentThread().sleep(50);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("结束task "+taskNum);    }}

参考:https://www.cnblogs.com/exe19/p/5359885.html

转载于:https://www.cnblogs.com/darknessplus/p/10359256.html

你可能感兴趣的文章
slab分配器
查看>>
数据清洗
查看>>
【读书笔记】C#高级编程 第三章 对象和类型
查看>>
针对sl的ICSharpCode.SharpZipLib,只保留zip,gzip的流压缩、解压缩功能
查看>>
【转】代码中特殊的注释技术——TODO、FIXME和XXX的用处
查看>>
【SVM】libsvm-python
查看>>
Jmeter接口压力测试,Java.net.BindException: Address already in use: connect
查看>>
Leetcode Balanced Binary Tree
查看>>
九.python面向对象(双下方法内置方法)
查看>>
go:channel(未完)
查看>>
[JS]递归对象或数组
查看>>
LeetCode(17) - Letter Combinations of a Phone Number
查看>>
Linux查找命令对比(find、locate、whereis、which、type、grep)
查看>>
路由器外接硬盘做nas可行吗?
查看>>
python:从迭代器,到生成器,再到协程的示例代码
查看>>
Java多线程系列——原子类的实现(CAS算法)
查看>>
在Ubuntu下配置Apache多域名服务器
查看>>
多线程《三》进程与线程的区别
查看>>
linux sed命令
查看>>
html标签的嵌套规则
查看>>