您现在的位置是:主页 > news > 网站seo博客/庆云网站seo

网站seo博客/庆云网站seo

admin2025/4/29 14:27:25news

简介网站seo博客,庆云网站seo,怎样做类似淘宝的网站,卖视频会员个人网站怎么做synchronized关键字在java中是用作线程同步的,保障同步区代码的正确执行,同一时间仅有一个线程进入同步区。其原理是使用锁技术,通过竞争,得到锁的线程执行同步区代码,未得到锁的线程自旋、阻塞等待。曾经synchronized…

网站seo博客,庆云网站seo,怎样做类似淘宝的网站,卖视频会员个人网站怎么做synchronized关键字在java中是用作线程同步的,保障同步区代码的正确执行,同一时间仅有一个线程进入同步区。其原理是使用锁技术,通过竞争,得到锁的线程执行同步区代码,未得到锁的线程自旋、阻塞等待。曾经synchronized…

synchronized关键字在java中是用作线程同步的,保障同步区代码的正确执行,同一时间仅有一个线程进入同步区。

其原理是使用锁技术,通过竞争,得到锁的线程执行同步区代码,未得到锁的线程自旋、阻塞等待。

曾经synchronized被认为是重量级的,获取和释放锁的过程耗时,影响并发性能。这种情况在java1.6后有所改善,java的作者们通过研究发现,synchronized同步区的锁在大部分时间下,并不会被多线程竞争,往往是一个线程进入执行完后反复获取锁或下一个线程取得锁。通过引入偏向锁、轻量级锁,减少了锁的获取、释放的耗时,提高性能。

锁是什么,java中的每个对象都可以作为锁,包括数组。如何表示锁被线程获取、锁的存储结构是什么样?

对象头

HotSpot虚拟机的java对象的存储可分为三部分:对象头、实例数据、对齐填充。

一般而言,对象头分为两部分:一部分称为Mark Word,这部分在不同位数虚拟机上存储长度不一样,32位虚拟机上是32bits,64位虚拟机上是64bits;另一部分是类型信息的指针;

Mark Word的存储结构并不是固定不变的,虚拟机会根据锁的状态调整存储,充分利用存储空间,如下图tag bits 列标识锁状态,在01时,会有额外的一位用于区分偏向锁,1标识偏向锁,0表示无锁。00时表示轻量级锁,10表示重量级锁,10是GC标记。

6a3d3b4ffba8e1dd2a4f7ee264845350.png

偏向锁、轻量级锁、重量级锁会发生单向的转换,只能从偏向锁向轻量级锁转换,轻量级锁向重量级转换。

偏向锁

在无线程竞争情况下,比如只有一个线程在同步区不断获取或释放锁,偏向锁级别会比较高效。线程只需要在对象头和当前线程栈帧中通过cas操作设置当前线程ID,下次进入同步区,只需要cas比对当前线程ID与Mark Word存储的是否一致,一致则代表获取到锁。如果这时候有其他线程也需要进入同步块,那cas比对必然失败,这时线程会继续测试Mark Work中偏向锁标识是否为1(1表示当前是偏向锁),如果没有设置,则使用CAS竞争锁,如果设置了,则尝试用CAS将Mark Word线程ID设置为当前线程。

所以在偏向锁时,偏向锁可以偏向不同线程,下面还会讨论偏向锁的撤销,从偏向锁变为无锁状态。

偏向锁撤销

偏向锁使用了当竞争出现时,才释放锁的机制,即如果某时刻一直只有一个线程进出临界区,其实它即使执行完临界区,锁也没有释放,Mark Word中的线程数据不会更改。当竞争出现,即有其他线程要进入临界区,这时需要撤销偏向锁。需要等待全局安全点(在这个时间点上没有正在执行的字节码)。它先暂停当前锁的持有线程,检测该线程是否存活,如果不存活,则将对象头设置为无锁状态,如果存活,先执行完当前栈,然后将对象头设置为无锁、偏向其他锁或不再适合偏向锁。最后唤醒暂停线程。

以上表述摘录并理解自《java并发编程艺术》一书,理解时,有以下疑问:

全局安全点,是否意味着偏向锁的持有线程当前肯定不在临界区中?不适合偏向锁是否意味着锁升级?

轻量级锁

加锁:将Mark Word复制到锁记录中,然后CAS替换对象头中的内容为锁记录指针。如果替换成功,则表示无竞争,线程获取锁;如果失败,则表示有竞争,

其它线程已经获取锁成功,当前线程通过自旋获取锁。自旋即非阻塞同步方式,不断在循环中尝试,是会消耗CPU的。

解锁:通过CAS操作将对象头中的指针替换回栈帧中的锁记录,替换成功则释放成功,替换失败则表示当前存在竞争,需要升级为重量级锁。

对于以上内容同样存在疑问:

当一个线程已经获取锁,即替换对象头中的数据为指针,这时候其他线程是如何判断这份数据是指针还是原始对象头数据的?数据本身有何特征?

当一个线程释放锁时,如果释放失败,那么当前对象头中存储的数据是什么?当前锁标识又存储的是什么?

重量级锁

获取不到锁的线程进入阻塞,获取到锁的线程,在释放锁时会有唤醒操作。

附上《java并发编程艺术》一书的几张图

415c4fa5d81f7908c174d83eb89d1367.png

a062fe7175be82f172f7129e8d96e7ea.png

b434e0a928352b79942d8d93733446f1.png

210df9986f97aefb341e82599a44bdb9.png