线程池
- 什么是线程池
- 是一种池化管理线程的机制,所谓的池化,比如就是预先把多个线程放在一个池子里,等到需要的时候就去池子里面取,这样就可以避免了线程频繁创建和销毁带来的影响,在java中,线程是一个比较重量的操作
- 线程池的作用
- 提高性能,因为重用存在的线程,减少线程创建和消亡的开销
- 提高响应速度,因为执行任务的时候不用等到线程取创建,可以直接从池子里面拿到线程就去等待cpu的调度。
- 可以管理线程,因为线程都在线程池里面,可以对线程进行同一的调度,分配和监控。
- 线程池怎么使用
- 线程池主要参数:
- corePoolSize,核心线程
- maximumPoolSize,线程池中最多的线程数
- keepAliveTime,表示空闲线程的存活时间(非核心线程,即时maximumPoolSize-corePoolSize的非核心线程数量)
- unit,keepAliveTime的单位
- workQueue,任务队列(SynchronousQueue,LinkedBlockingQueue,)
- RejectedExecutionHandler,拒绝策略,拒绝策略有4种:
- CallerRunsPolicy,由调用execute方法提交任务的线程来执行这个任务,由调用方来直接执行该任务
- AbortPolicy,抛出异常RejectedExecutionException拒绝提交任务;
- DiscardPolicy,直接抛弃任务,不做任何处理;
- DiscardOldestPolicy,丢弃策略,去除任务队列中的第一个任务(最旧的),重新提交;
- 线程池有那些
- newCachedThreadPool,一种可缓存的线程池,corePoolSize=0,最大线程数maximumPoolSize为Integer.MAX_VALUE,keepAliveTime为60s,意味着线程空闲时间超过60S就会被杀死,workQueue为SynchronousQueue。是根据需要创建的新线程的线程池,如果线程池没有没有的线程,就创建一个新线程并添加到池子里面,如果有空闲的线程而且还没被销毁的化就复用该线程,线程空闲时间超过60s,会被移除。SynchronousQueue是一个没有数据缓冲的阻塞队列,长度为0,不会缓存任何数据,也就是只要有请求到来,就必须要找到一条工作线程处理他。
- newFixedThreadPool,固定大小的线程,核心线程数和最大核心线程数都是固定传入的值,假设值是10,同时最多有10个线程去执行任务,超过10个的时候,把任务放在工作队列里面,这里的任务队列用的是LinkedBlockingQueue无界队列。
- newSingleThreadExecutor,核心线程数和最大线程数都是1,也就是最多只能有一个任务在执行,超过1个任务,超过1个任务都会放在队列LinkedBlockingQueue里面
- 自定义线程池,假设设置corePoolSize核心线程数是10,最大线程数20,如果我们设置LinkedBlockingQueue的长度为10的话,那么将在第31个任务的时候出错,要做拒绝策略
- 线程池流程

map
hashmap
1.7的hashmap是用数组+链表实现,链表的插入是用头插法,头插法会导致死循环。
1.8的hashmap是用数组+链表+红黑数实现的,链表的插入是用尾插法。是链表在数组容量大于64,而且链表长度大于8的时候,链表转成红黑树。
hashmap都是线程不安全的
为解决hashmap的线程安全问题,引入了ConcurrentHashMap
ConcurrentHashMap解决线程安全:主要是用了Unsafe的cas操作+synchronized来实现的
synchronized主要负责在需要操作某个位置时,是数组的某个位置,而不是整个数组加锁进行加锁,例如put方法

