大家好久不见啊!今天来学习新的知识——Java并发编程,如果有什么疑问欢迎评论区共同讨论,也可以在网络上找寻其他相关的详细知识点!
并发编程三种性质
1.原子性
原子,即一个不可再被分割的颗粒。在Java中原子性指的是一个或多个操作要么全部执行成功要么全部执行失败。
2.有序性
程序执行的顺序按照代码的先后顺序执行。(处理器可能会对指令进行重排序)
3.可见性
当多个线程访问同一个变量时,如果其中一个线程对其作了修改,其他线程能立即获取到最新的值。
并发编程三个问题
1.安全性的问题:线程安全
2.活跃性的问题:死锁问题、活锁、饥饿
3.性能问题:
(1)使用无锁结构:TLS线程局部存储、Copy-On-Write、乐观锁、Java的原子类、 Disruptor无锁队列
(2)减少锁的持有时间:锁粒度的细化,ConcurrentHashMap;可以使用读写锁
valitate关键字
Java会将变量直接写入内存,其它线程读取时直接从内存读取。同时禁止指令重新排序
volatile是一种轻量级线程安全机制;保证可见性和有序性,不能保证原子性。
原理:
1. 使用volitate修饰的变量在汇编阶段,会多出一条lock前缀指令
2. 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成
3. 它会强制将对缓存的修改操作立即写入主存
4. 如果是写操作,它会导致其他CPU里缓存了该内存地址的数据无效
synchronized关键字
synchronized 是JVM实现的一种锁,其中锁的获取和释放分别是monitorenter 和 monitorexit 指令,该锁在实现上分为了偏向锁、轻量级锁和重量级锁,其中偏向锁在 java1.6 是默认开启的,轻量级锁在多线程竞争的情况下会膨胀成重量级锁,有关锁的数据都保存在对象头中。
锁对象:非静态this、静态Class、括号Object参数
预防死锁:(死锁的4个必要条件)
1.互斥条件:不能破坏
2.占用且等待条件:同时申请所有资源
3.不可抢占条件:synchronized解决不了,Lock可以解决
4.循环等待条件:给资源设置id字段,每次申请资源时必须按照顺序申请
等待通知机制
1.wait notify和notifyAll
2.生产者消费者模式
(1)sychronized同步锁一共包含4种状态:无锁、偏向锁、轻量级锁、重量级锁,会随着竞争状况逐步升级;sychronized同步锁可以升级,但是没有降级处理,目的在于提高获取锁和释放锁的效率
(2)sychronized修改的代码块经过反编译.class文件查看字节码文件可以得到:在代码块中使用的是 monitorenter和monitorexit指令指向同步代码块的开始和结束位置
(3)sychronized修饰方法查看字节码可得:同步方法中会包含一个ACC_SYNCHRONIZED 标识符,使用该标识符指定给方法是一个同步方法,从而执行相应的同步调用
今天的学习就先到这里吧,下一篇我们继续学习有关于锁分类,以及其余相关知识点,欢迎大家的指正与讨论,让我们一起共同努力!