synchronized
- synchronized 的修饰对象
- 静态方法 获得本类对象
- 方法 本实例对象
- 代码块: 可以指定锁对象
- 原理
当程序执行到synchronized 修饰段的时候,线程会尝试获取它的监视器对象
如果监视器进入数为0 则该线程获得监视器,然后设置进入树为1 可重入
如果monitor 对象已经被其他线程获取,则该线程进入阻塞状态,直到monitor 进入数为0
- wait notify
wait 和 notify 就是一个暂停运行 一个通知运行,当时必须获得锁以后才可以执行该对象,而且获得的锁必须是相同的锁机制。
锁的原理也是获得监控器的对象,
wait 立刻释放锁
notify 一次只唤醒一个线程且唤醒的顺序和执行wait方法的顺序一致 - volatile 关键字
保证可见性
不保证原子性
禁止指令重排
守护进程和用户进程
用户进程就是用户创建的进程
不需要上乘逻辑介入
主线程结束 自动结束
普通线程是一直run 完 可能
阻塞队列
- 普通阻塞队列
- 数组阻塞队列
一旦指定了队列的长度,则队列的大小不能改变 先进先出 数组实现
- 列表阻塞队列
先进先出 可以设置有限也可以设置无限 - 优先阻塞队列
插入的对象必须可以比较的 - 异步阻塞队列
put 必须等待take take也必须等待put - lock 和 synchronized 的区别
lock 是一个类 发送异常不会释放锁
synchoronized 不会释放锁
线程池
- 线程池的配置
CPU 密集性 +1
IO密集型 CPU/(1-阻塞系数) - 线程池的参数
核心线程数
最大线程数
存活时间
存活时间单位
任务队列
线程工厂
拒绝策略
拒绝策略比如不管什么情况直接抛出异常
或者任何处理继续运行
- 线程池的创建
1.newCachedThreadPool创建一个可缓存线程池程
2.newFixedThreadPool 创建一个定长线程池
3.newScheduledThreadPool 创建一个定长线程池
4.newSingleThreadExecutor 创建一个单线程化的线程池
锁机制
公平锁就是按申请顺序执行
非公平锁就是部分优先级高的可以加塞
可重入锁就是进入锁内部仍然可以获得该锁
不停地空耗CPU
中心锁默认是非公平的
乐观锁默认操作不会修改数据 使用CAS
悲观锁默认会修改数据 使用Synchronized
在对记录进行修改前,先尝试为该记录加上排他锁(exclusive locks)。
如果加锁失败,说明该记录正在被修改,那么当前查询可能要等待或者抛出异常。具体响应方式由开发者根据实际需要决定。
如果成功加锁,那么就可以对记录做修改,事务完成后就会解锁了。
期间如果有其他对该记录做修改或加排他锁的操作,都会等待解锁或直接抛出异常。
死锁
死锁预防是添加某种限制条件
比如设定某线程必须在另一个线程全部执行完之后才能执行
sleep yeild
①sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
④ sleep()方法比yield()方法(跟操作系统CPU调度相关)具有更好的可移植性。
AQS 抽象对垒同步器