一、并发编程的挑战
1.1上下文切换
并发测试线程的创建和上下文的切换带来的开销,导致部分情况下并发执行的速度比串行的慢。
1.2死锁
死锁的产生:
多个线程对资源的竞争,导致的互相等待。
常用避免死锁的方法:
- 避免一个线程同时获取多个锁
- 避免一个线程在同一个锁内占用多个资源,尽量保证每个锁只占用一个资源
- 尝试使用定时锁机制,使用lock.trylock(timeout)来替代
- 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况
二、Java并发机制的底层实现
2.1 volatile
对变量的原子操作
原理
将处理器的缓存数据写回到系统内存,同时这个操作会让其他CPU里缓存该内存数据无效。
2.2 synchronize 的实现原理
锁对象synchronize 用的锁是存在Java对象里的。
锁的类型
锁的类型偏向锁:认为没有人竞争。
轻量级锁:竞争不激烈,占用对象耗时少。
重量级锁:排他性。
原子操作
java中通过锁和CAS的方式来实现原子操作
CAS:对比数据的值以及版本的方式。
CAS实现原子操作的三大问题
- ABA问题,即值从A到B再到A,无法单纯通过值判断变量是否改变,故引入了版本号
- 循环时间长开销大,引入了处理器指令的PAUSE。
- 多个共享变量的操作,引入了对象的原子性。
四、java并发基础
4.1.3线程优先级
线程优先级4.1.4线程的状态
线程的状态4.1.5Deamon线程
daemon线程deamon线程注意
4.2.5安全的中止线程
安全中止线程4.3 线程通信
4.3.3 等待通知模式
等待/通知模式4.3.4 管道输入输出
分两种:
管道
- 字节流:PipedOutputStream,PipedInputStream
- 字符流:PipedReader,PipedWriter
4.4 线程应用实例
4.4.1 等待超时模式
五、Java中的锁
5.1 Lock接口
显示的获取锁,释放锁。
Lock接口提供synchronized不具备的特性
Lock的api
5.2.1 队列同步器实现的独占锁
同步器可重写的方法独占锁
共享锁,支持两个线程
5.3 重入锁
支持单线程多次获取锁5.4 读写锁
多线程重入读锁,单线程重入写锁5.5 LockSupport 工具
手动操作锁工具类5.6 condition接口
任意一个java对象通过监视器方法(wait、notify等)与synchronized配合,可以实现等待通知模式
Object的监视器和Condition接口对比
网友评论