<b><font face="思源黑体">进程和线程</font></b>
<b><font face="思源黑体">进程:运行中的程序就是一个进程(特点:宏观并行,微观串行)</font></b>
<b><font face="思源黑体">线程:程序中的控制流程,它是CPU的调度单元</font></b>
<b><font face="思源黑体">关系:一个进程中包含一个或多个线程</font></b>
<b><font color="#e74f4c">创建线程(重点)</font></b>
<b><font face="思源黑体">1.通过继承Thread类</font></b>
<b><font face="思源黑体">2.实现Runnable接口</font></b>
两种方式的区别:
<b><font face="思源黑体">1.创建Thread类,那么当前类就是一个线程类。实现Runnable接口当前这个类只是一个线程任务。</font></b>
<b><font face="思源黑体">2.在java中只支持单继承,所以实现Runnable更加的灵活</font></b>
线程的常用方法
1.设置线程名(setName、getName(获取线程名))
若没有设置,默认名为Thread-N
2.设置线程优先级(setPriority、getPriority)
若没有设置,默认优先级为5,设置优先级只能提高抢占CPU的概率
3.线程休眠(Thread.sleep(毫秒数))
让当前线程进入休眠状态,并让出CPU使用权,直到休眠结束才会继续抢占CPU
4.线程礼让(yeild)
本次会立马让出CPU使用权,但是立马会去抢下次的CPU使用权
5.线程加入(join)
在当前线程中加入另一线程,必须要将另一个线程执行完之后才会继续执行当前线程
<b><font face="思源黑体" color="#e74f4c">线程安全(重点)</font></b>
<b><font face="思源黑体">线程不安全:</font></b>
<b><font face="思源黑体">多个线程操作<font color="#e74f4c">临界资源</font>,破坏<font color="#e74f4c">原子操作</font>,可能会造成数据不一致</font></b>
<b><font face="思源黑体">如何解决线程不安全:</font></b>
<b><font face="思源黑体">1.同步代码块</font></b>
<b><font face="思源黑体">synchronized(临界资源对象){ //互斥锁标记</font></b>
<b><font face="思源黑体">2.同步方法</font></b>
<b><font face="思源黑体">public synchronized void sale(){ //互斥锁标记是this对象</font></b>
<b><font face="思源黑体">线程同步买票问题</font></b>
<b><font face="思源黑体">1.同步方法</font></b>
<b><font face="思源黑体">2.同步代码块</font></b>
<font color="#e74f4c" face="思源黑体"><b>线程的生命周期</b></font>
<b><font face="思源黑体">线程死锁</font></b>
<b><font face="思源黑体">当第一个线程拥有A对象的锁标记,并等待B对象的所标记。同时第二个线程拥有B对象锁标记,同时等待A对象的锁标记时,产生死锁</font></b>
<b><font face="思源黑体">线程池</font></b>
<b><font face="思源黑体">原理</font></b>
<b><font face="思源黑体">静态线程池(<font color="#e74f4c">newFixedThreadPool(指定线程数</font>))</font></b>
<b><font face="思源黑体">动态线程池(<font color="#e74f4c">newCachedThreadPool()</font>)</font></b>
<b><font face="思源黑体">Callable接口和Future接口</font></b>
<b><font face="思源黑体">区别:</font></b>
<b><font face="思源黑体">1.这两个接口都可以当做线程任务提交并执行</font></b>
<b><font face="思源黑体">2.Callable接口执行完线程任务之后有返回值,而Runnable接口没有返回值</font></b>
<b><font face="思源黑体">3、Callable接口中的call方法已经抛出了异常,而Runnable接口不能抛出编译异常</font></b>
<b><font face="思源黑体">线程池7个核心参数</font></b>
<b><font face="思源黑体">1.corePoolSize</font></b>
核心线程池大小即初始化的线程数
<b><font face="思源黑体">2.maximumPoolSize</font></b>
最大线程池大小
<b><font face="思源黑体">3.keepAliveTime</font></b>
线程池的最大空闲时间,超过这个时间后,空闲线程会被回收
<b><font face="思源黑体">4.unit</font></b>
keepAliceTime的时间单位
<b><font face="思源黑体">5.workQueue</font></b>
任务队列,用于存放等待执行的任务
<b><font face="思源黑体">6.threadFactory</font></b>
线程工厂,用于创建新线程
<b><font face="思源黑体">7.handler</font></b>
拒绝策略,用于处理无法处理的任务
常见的任务队列
直接提交任务队列
有界任务队列
无界任务队列
优先任务队列
延迟任务队列
可靠性任务队列
并行任务队列
<b><font face="思源黑体">Lock锁</font></b>
<br>
<b><font face="思源黑体">synchronized和Lock锁的区别:<br>1、Lock是Java中的类,synchronized是Java中的关键字<br>2、Lock是显示的上锁和释放锁,而synchronized自动上锁和释放锁<br>3、当同步代码出现异常,Lock不会自动释放锁(可能会出现死锁),synchronized会自动释放锁对象<br>4、Lock锁和synchronized锁都可以实现重入锁(避免死锁)<br>5、Lock锁可以实现公平锁和非公平锁,synchronized不能实现公平锁<br>6、Lock中提供了读写锁(特点:读读不互斥。读写互斥。写写互斥)</font></b>
<b><font face="思源黑体">读写锁</font></b>
<font face="思源黑体"><b>重入锁</b></font>
<font face="思源黑体"><b>公平锁</b></font>
<font face="思源黑体"><b>synchronized锁升级</b></font>
1.无锁
当锁对象被创建,还没有线程进入的时候,此时锁对象出于无锁状态
2.偏向锁
线程A进入同步代码并获得锁对象时会保存线程id,以后线程A进入到同步代码中无需使用CAS加锁或释放锁,只需要验证线程id
3.轻量级锁(自旋锁)
当前锁处于偏向锁,后面线程B进入到同步代码,线程AB会使用CAS竞争并升级为轻量级锁
4.重量级锁
若线程没有获得轻量级锁,且自旋次数大于阈值(10次),则会升级为重量级锁
<b><font face="思源黑体">互斥锁标记:任意java对象,一定要保证<font color="#e74f4c">唯一</font></font></b>