wait() 和 sleep() 方法的区别
- 来源不同:sleep来源于Thread类,而wait方法来源于Object类;
- 对同步锁的影响不同:sleep不会释放锁,wait会释放锁;
- 使用范围不同:sleep可以在任何地方使用,wait只能在同步控制方法或同步控制块中使用,否则会抛出异常。
- 恢复方式不同:sleep之后,时间到了会自动恢复,wait只能通过notify或者notifyAll才能进行唤醒。
join()方法是做什么的
将其他线程临时加入,并等待其执行完成;
多线程程序的实现方式
- 继承Threand类;
- 实现Runnable接口;
- 实现Callable接口;
- 线程池;
线程的状态及流转
状态:新建、就绪、阻塞、运行、等待、终止
- 新建:尚未执行start()方法,还没开始运行;
- 就绪:已经执行start()方法,还没获取到CPU时间;
- 运行:当线程成功获取到CPU时间后,立即进入运行;
- 阻塞:进入同步方法,获取不到锁时进入阻塞;
- 等待:等待手动唤醒的状态,例如执行了wait方法;
- 终止:执行完毕退出
死锁的条件
- 互斥条件:一段时间内同一资源只能有一个进程使用;
- 请求和保持条件:进程需要请求其他资源,但是其他资源正在被其他进程使用,此时进程对手中资源又保持不释放;
- 不可剥夺条件:已获得的资源在进程没有使用完毕前,只能自己主动释放,不能被其他进程强制释放;
如何避免死锁
- 打破互斥:取消互斥,避免资源独占;
- 打破请求保持:进程要么一次申请到所有资源,要么就等待。或者是进程申请其他资源时,及时释放手中的资源;
- 打破不可剥夺:已经占用资源后无法获取到其他资源,应该及时释放原有资源
线程池的核心参数
- 最大线程数(超过线程池的线程为非核心线程)
- 线程池大小
- 非核心线程的存活时间
- 线程队列
- 拒绝策略:当线程池已满时,继续添加线程会触发拒绝。
1.丢弃报错(默认)
2.丢弃不报错
3.丢弃队首的线程
当服务为CPU密集性时,需要扩展机器
当服务为IO密集型时,线程数一般定位CPU核心数的2倍
ThreadLocal
线程的本地变量,每当创建一个线程,都会有一个副本。
内部时通过一个map来进行存储