1.目的
本文档目的主要是学习多线程。设计一些自己的理解。原子类、线程池、使用方式记录。
2.线程池
2.1线程池目的
线程池好处:出自《Java并发编程的艺术》
- 降低资源消耗。通过重复利⽤已创建的线程降低线程创建和销毁造成的消耗。
- 提⾼响应速度。当任务到达时,任务可以不需要的等到线程创建就能⽴即执⾏。
- 提⾼线程的可管理性。线程是稀缺资源,如果⽆限制的创建,不仅会消耗系统资源,还会降 低系统的稳定性,使⽤线程池可以进⾏统⼀的分配,调优和监控
2.2 Runnable和Callable的区别
Runnable和Callable 都可以执行一个任务。
Runnable
⾃ Java 1.0 以来⼀直存在,但 Callable
仅在 Java 1.5 中引⼊,⽬的就是为了来处
理 Runnable
不⽀持的⽤例。 Runnable
接⼝不会返回结果或抛出检查异常,但是 Callable
接⼝
可以。所以,如果任务不需要返回结果或抛出异常推荐使⽤ Runnable
接⼝,这样代码看起来会
更加简洁。
⼯具类 Executors 可以实现 Runnable 对象和 Callable 对象之间的相互转换。
可以使用Executors创建线程池。但是阿里的开发文档不推荐,主要是因为默认的任务队列的长度是Integer.MAX_VALUE。 如果稍不小心,会造成OOM
Executors内部的方法实际是调用的 ThreadPoolExecutor
的构造方法。
所以我们看一下ThreadPoolExecutor
的构造参数及含义。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
ThreadPoolExecutor
类中提供的四个构造⽅法。我们来看最⻓的那个,其余三个都是在这个构造⽅法的基础上产⽣(其他⼏个构造⽅法说⽩点都是给定某些默认参数的构造⽅法⽐如默认制定拒绝策略是什么)。
corePoolSize
:核⼼线程数线程数定义了最⼩可以同时运⾏的线程数量。maximumPoolSize
: 当队列中存放的任务达到队列容量的时候,当前可以同时运⾏的线程数量变为最⼤线程数。workQueue
: 当新任务来的时候会先判断当前运⾏的线程数量是否达到核⼼线程数,如果达到的话,新任务就会被存放在队列中