1.创建线程资源使用线程池,原因:线程池能减少创建和销毁线程所消耗的时间和系统开销,解决系统资源不足的问题
2.线程池通过ThreadPoolExecutor,规避了资源耗尽
3.多线程创建的方式
继承Thread类
实现Runnable接口
线程池
Callable + FutureTask
CompletableFuture
Fork Join
并行计算
Timer定时任务
Spring异步方法调用
4.线程状态
NEW:新建,未启动
RUNNABLE:就绪,已启动,等待cpu时间片
RUNNING:运行,正在执行
BLOCKED:阻塞,遇到synchronized未得到锁
WAITING:等待,执行了wait(),需要被notify()或notifyAll()唤醒
notify():随机唤醒一个等待的线程
notifyAll():唤醒所有等待的线程
TIMED_WAITING:限时等待,调用了Thread.sleep()或wait,设置了时间
TERMINATED:结束
5.虚假唤醒
两个以上的线程会造成虚假唤醒,即没有使用notify(),线程自己苏醒自动执行任务,使用While循环解决
6.锁
多个线程申请锁,某个线程得到锁之后,在对象监视器上留下记录,等到该线程执行完,要释放锁时,清除在对象监视器上留下的记录,然后释放锁。
对象监视器(ObjectMonitor)是c++开发的
7.synchronized字节码指令
加锁:monitorenter
解锁:monitorexit
8.锁膨胀机制(jdk1.6引入,目的:如果只有一个线程,则没有锁的竞争,不需要加锁、解锁,节约操作时间)
无锁:没有线程申请锁
偏向锁:只有一个线程,并且是同一线程申请锁
轻量级锁:只有一个线程,但是是不同线程申请锁
重量级锁:多个线程申请锁
锁膨胀不可逆
9.对象结构
对象头:对象运行时信息
对象体:对象本身的属性数据
对齐字节:填充数据,8字节的整数倍