java并发编程知识点总结

和之前一篇多线程文章类似,这里没有什么逻辑顺序就是一些知识点,也不是很深入,见谅!


1、不是有越多的线程程序运行的越快,因为在并发编程时,会有更多的上下文切换,死锁等问题。

2、上下文切换:CPU通过时间片 分配算法来循环执行任务,当前任务执行完一个时间片之后会切换到下一个任务,但是又要保存上一个任务的状态,以便下一次可以加载到上一状态,所以任务从保存到在加载的过程叫做上下文切换。

3、如何减少上下文切换?   

无锁并发编程:多线程因为有所会出现很多竞争,所以尽量避免锁,EG:将数据的ID按照hash算法取模分段,不同的线程处理不同的段的数据。

CAS算法:Java的Atomic包使用CAS算法来更新数据,不需加锁。

使用最少线程:避免创建不需要的线程。

协程:在单线程里实现多任务调度,并在单线程里维持多个任务间的切换。

4.避免死锁的办法:

  避免一个线程同时获得多个锁

避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源

尝试使用定时锁,使用lock.tryLock(timeout)来代替使用内部锁机制

对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况

 

Java并发机制的底层实现、

Java代码编译后会变成Java字节码,字节码被类加载器加载到jvm里,jvm执行字节码,最终转换成汇编指令在CPU上运行,Java所使用的并发 机制依赖jvm的实现和CPU的指令。

volatile

volatile的应用:volatile是轻量级的Synchronized,他保证了共享变量的可见性,(可见性是指:当一个线程修改一个共享变量的值时,另一个线程可以读取这个修改的值)、恰当使用volatile会比Synchronize效率高,因为volatile不会有上下文切换和调度。

Volatile的定义:允许线程访问共享变量,为了确保共享变量可以一致的更新,应该通过排它锁单独的获得这个变量。

1.Volatile原理:1.Lock前缀指令会引起处理器缓存写到内存:

2.一个处理器的缓存写到内存会导致其他处理器的缓存无效。

volatile的优化:jdk7中增加了一个队列集合类:LinkedTransferQueue  他在使用volatile变量时,通过追加字节的方法来优化队列的出栈和入栈性能。

那么他是如何优化的呢?原来缓存行的大小是64字节,所以使用追加的方法填充缓存行,这样的话就避免了头结点和尾节点在一行,这样在修改时也不会相互锁定。

 

在两种情况下不能用这种优化方法:1,当缓存行的大小不是64,2.当没有对共享变量频繁的写

 

Synchronize

Synchronize也被称为重量级锁,因为在获得锁和释放锁都会带来性能消耗

Synchronize实现锁有三种表现形式:

1.对于普通的同步方法,锁的是当前的实例变量

2.对于静态的同步方法,锁的是当前类的class对象

3.对于同步同步方法块,锁的是{}配置的对象。

 

 

锁的升级与对比:为了减少锁申请和释放带来的性能消耗,引入了“偏向锁”“轻量级锁”。

锁一共有四种状态:无锁状态,偏向锁状态,轻量级锁状态,重量级锁状态。

锁可以升级但是不能降级。

 

  偏向锁:由于大多数情况下锁其实不具有竞争状态,所以出现了该锁,基本的思想是:当一个线程访问一个同步块并且获取锁时,会在对象头和帧栈中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出该同步块时,不需要用CAS来加锁和解锁,只需要简单测试一下对象头里的MarkWord里是否存了指向当前线程的偏向锁,要是有,表示已经获得锁;

 

偏向锁的撤销,使用了一种等到有竞争才释放的机制,也就是说,当其他线程请求的时候才会释放。同时释放的时候需要等到安全点,即在这个点上没有正在执行字节码。偏向锁是自动开启的,要实现两关闭,则通过-XX:BiasedLockingStartupDelay=0来设置。设置之后就默认进入轻量级锁。


 

锁的优缺点:

优点

缺点

适用场景

偏向锁

加锁和解锁不需要额外的开销,和执行费同步方法只有纳秒级的差别。

若线程之间存在锁竞争,会带来额外的锁撤销的消耗。

适用于只有一个线程访问同步块的场景。

轻量级锁

竞争的线程不会阻塞,提高了程序的响速度

如果始终得不到锁竞争的线程会陷入自旋,会消耗CPU

追求响应时间 同步块执行速度非常快

重量级锁

线程竞争不会自旋

线程阻塞,响应时间慢

追求吞吐量

同步块执行速度较长

 

原子操作

原子操作是不能被分割的一系列操作。

基于缓存行加锁和总线加锁的方式来实现原子操作

缓存锁锁掉了内存和CPU之间的通信,开销比较大,所以现在用的是缓存行加锁。

但有两种情况不会使用缓存行锁:

操作的数据不能被缓存或则一个缓存行不够存储

有些处理器不支持缓存锁定


Java如何实现原子操作:可以通过锁和循环CAS来实现。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值