当前位置: 主页 > JAVA语言

java 锁-java 对象锁

发布时间:2023-02-09 16:39   浏览次数:次   作者:佚名

1.同步

在JDK 1.6之前,synchronized是一个重量级的锁,效率很低。

从JDK 1.6开始,synchronized做了很多优化,比如偏向锁、轻量级锁、自旋锁、自适应自旋锁、锁淘汰、锁粗化等技术,减少锁操作的开销。

一个synchronized同步锁包括四种状态:无锁、偏向锁、轻量级锁和重量级锁。 它将随着竞争逐步升级。 synchronized同步锁可以升级,不能降级。 目的是提高获取和释放锁的效率。

synchronized 同步修改代码块的底层原理

通过反编译.class文件,查看字节码,可以发现代码块中使用了monitorenter和monitorexit指令,其中monitorenter指令指向同步代码块的起始位置,monitorexit指令表示同步代码块的结束位置。

同步修改方法

您还可以查看字节码:ACC_SYNCHRONIZED 标志将包含在同步方法中。 该标记表明该方法是一个同步方法,从而执行相应的同步调用。

2.对象锁、类锁、私有锁

对象锁:使用synchronized修饰非静态方法,synchronized(this)同步代码块使用的锁是对象锁。

java互斥锁和同步锁_java 锁_java 对象锁

类锁:使用synchronized修饰静态方法,synchronized代码块使用的synchronized(类)锁就是类锁。

私有锁:在类内部声明一个私有属性如private Object lock,在需要加锁的同步块中使用synchronized(lock)

他们的特点:

私有锁实现的等待/通知机制:

Object lock = new Object();// 由等待方线程实现synchronized (lock) {
    while (条件不满足) {
       lock.wait();
   }                         }// 由通知方线程实现synchronized (lock) {

java 锁_java互斥锁和同步锁_java 对象锁

条件发生改变 lock.notify(); }

3.可重入锁

ReentrantLock 是排他/独占锁。 与synchronized相比,更加灵活。 但是加锁和解锁的过程需要自己写。 它的灵活性在于它的许多特性。

ReentrantLock 需要显式释放锁。 特别是当程序出现异常时,synchronized会自动释放锁,而ReentrantLock不会自动释放锁,所以必须在finally中释放锁。

其特点:

ReentrantLock 是许多类的基础。 比如ConcurrentHashMap内部使用的Segment继承了ReentrantLock,CopyOnWriteArrayList也使用了ReentrantLock。

java互斥锁和同步锁_java 锁_java 对象锁

4. 可重入读写锁

之前写过一篇文章《ReentrantReadWriteLock读写锁及其在RxCache中的使用》java 锁,里面详细介绍了ReentrantReadWriteLock。

它有读锁(ReadLock)和写锁(WriteLock),读锁是共享锁,写锁是排它锁。

其特点:

5.中科院

上面提到的ReentrantLock和ReentrantReadWriteLock是基于AbstractQueuedSynchronizer(AQS)的,而AQS是基于CAS的。 CAS的全称是Compare And Swap(比较和交换),是一种无锁算法。

synchronized和Lock都是采用悲观锁的机制,而CAS是乐观锁的一种实现。

CAS的特点:

java 对象锁_java互斥锁和同步锁_java 锁

CAS 的问题:

6. 条件

Condition用于替代传统Object的wait()和notify()实现线程间的协作。

在Condition对象中,wait、notify、notifyAll对应的方法分别是await、signal、signalAll。

Condition 必须与 Lock 一起使用java 锁,并且 Condition 的实例必须绑定到 Lock。

其特点:

7.信号量

Semaphore、CountDownLatch、CyclicBarrier 都是并发工具类。

java 锁_java 对象锁_java互斥锁和同步锁

Semaphore可以指定多个线程同时访问一个资源,而synchronized和ReentrantLock都只允许一个线程一次访问一个资源。 由于Semaphore适合限制访问某些资源的线程数,所以可以用来节流。

Semaphore没有实现数据同步,数据同步仍然需要使用synchronized、Lock等实现。

其特点:

八。 倒数锁存器

CountDownLatch 可以被认为是一个倒计时计数器,它允许一个或多个线程等待其他线程完成操作。 因此,CountDownLatch 是一个共享锁。

CountDownLatch 的 countDown() 方法会将计数器减 1,而 await() 方法会阻塞当前线程,直到计数器变为 0。

在我的爬虫框架NetDiscovery中使用CountDownLatch来控制爬虫的挂起和恢复。

九。 锁的分类

java 对象锁_java 锁_java互斥锁和同步锁

十、总结

本文总结了Java中常用的一些锁及其一些特点。 掌握这些锁是掌握Java并发编程的基础。 当然,Java的锁不限于这些,比如ConcurrentHashMap的段锁(Segment),分布式环境下使用的分布式锁。