1. NEW(新建状态):创建后,启动前。线程就处于该状态。
2. RUNNABLE(可运行状态):线程正在执行代码,就处于该状态。
3.BLOCKED(阻塞状态):一个线程获取synchronized锁对象失败,就处于该状态。
4. WAITING(无限等待):调用wait方法,线程处于该状态。
5.TIMED_WAITING(计时等待状态):线程正在执行sleep方法,就处于该状态。
6.TERMINATED(消亡状态):线程把任务执行完毕后,就处于该状态。

1. corePoolSize 核心线程数目 - 池中会保留的最多线程数
2. maximumPoolSize 最大线程数目 - 核心线程+救急线程的最大数目
3. keepAliveTime 生存时间 - 救急线程的生存时间,生存时间内没有新任务,此线程资源会释放
4. unit 时间单位 - 救急线程的生存时间单位,如秒、毫秒等
5. workQueue - 当没有空闲核心线程时,新来任务会加入到此队列排队,队列满会创建救急线程执行任务
6. threadFactory 线程工厂 - 可以定制线程对象的创建,例如设置线程名字、是否是守护线程等
7. handler 拒绝策略 - 当所有线程都在繁忙,workQueue 也放满时,会触发拒绝策略
1. 抛异常 java.util.concurrent.ThreadPoolExecutor.AbortPolicy
2. 由调用者执行任务 java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy
3. 丢弃任务 java.util.concurrent.ThreadPoolExecutor.DiscardPolicy
4. 丢弃最早排队任务 java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy

共同点
wait() ,sleep的效果都是让当前线程暂时放弃 CPU 的使用权,进入阻塞状态
方法归属不同
sleep 是 Thread 的静态方法,wait 是 Object 的成员方法
醒来时机不同
它们都可以被打断唤醒
锁特性不同
wait 方法的调用必须先获取 wait 对象的锁,而 sleep 则无此限制
wait 方法执行后会释放对象锁,允许其它线程获得该对象锁(我放弃 cpu,但你们还可以用)
而 sleep 如果在 synchronized 代码块中执行,并不会释放对象锁(我放弃 cpu,你们也用不了)
1、悲观锁的代表 Synchronized 和 Lock 锁
线程只有占有了锁才能操作共享变量,每次只有一个线程占锁成功,获取锁失败都得停下来等待。线程从运行到阻塞、再从阻塞到唤醒,涉及线程上下文切换,如果频繁发生,影响性能
2、乐观锁的代表是 AtomicInteger,使用 cas 来保证原子性
无需加锁,每次只有一个线程能成功修改共享变量,其它失败的线程不需要停止,不断重试直至成功。需要多核 cpu 支持,且线程数不应超过 cpu 核数
1、都可以用于多线程的环境
2、ConcurrentHashMap仅仅锁定map的某个部分,而Hashtable则会锁定整个map
1、HashMap不是线程安全的,而ConcurrentHashMap是线程安全的。
2、ConcurrentHashMap采用锁分段技术,将整个Hash桶进行了分段segment,也就是将这个大的数组分成了几个小的片段segment,而且每个小的片段segment上面都有锁存在,那么在插入元素的时候就需要先找到应该插入到哪一个片段segment,然后再在这个片段上面进行插入,而且这里还需要获取segment锁。
可见性、有序性、不能保证原子性
可见性:volatile声明变量,保证不会被JIT编译器优化,避免更新了该变量线程仍使用旧值
有序性:volatile使用内存屏障来保证指令不被重排
线程间实现资源线程隔离,线程内实现资源共享
原理:每个线程内部都有一个ThreadLocalMap存储资源对象,set 就以ThreadLocal自己作为key存储对象
ThreadLocalMap为何设计为弱引用:
1、线程可能需要运行时间很长(如线程池中线程),一些不被使用key,需要在内存不足的时候被回收
2、GC仅让key的内存释放,后续需要根据key为null对值内存进行释放