java多线程研究: 锁的概念

23 篇文章 0 订阅
14 篇文章 1 订阅
ReentrantLock和synchronized两种锁定机制的对比
synchronized:
synchronized (lockObject) {   
  // update object state  
}  

这是一个独享非公平可重入锁。
把代码块声明为 synchronized,有两个重要后果,通常是指该代码具有 原子性(atomicity)和 可见性(visibility)。原子性意味着一个线程一次只能执行由一个指定监控对象(lock)保护的代码,从而防止多个线程在更新共享状态时相互冲突。
可见性则更为微妙;它要对付内存缓存和编译器优化的各种反常行为。

缺点:
无法中断一个正在等候获得锁的线程。
无法通过投票得到锁,如果不想等下去,也就没法得到锁。
synchronized是一个重量级的锁。

ReentrantLock 类:

这是一个独享非公平可重入锁。
java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现。这就为 Lock 的多种实现留下了空间,各种实现可能有不同的调度算法、性能特性或者锁定语义。
ReentrantLock 类实现了 Lock ,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。
ReentrantLock 默认是非公平锁。

Lock lock = new ReentrantLock();  
lock.lock();  
try {   
  // update object state  
}  
finally {  
  lock.unlock();   
} 
什么时候选择用 ReentrantLock 代替 synchronized

既然如此,我们什么时候才应该使用 ReentrantLock 呢?答案非常简单 —— 在确实需要一些 synchronized 所没有的特性的时候,比如时间锁等候、可中断锁等候、无块结构锁、多个条件变量或者锁投票。 ReentrantLock 还具有可伸缩性的好处,应当在高度争用的情况下使用它,但是请记住,大多数 synchronized 块几乎从来没有出现过争用,所以可以把高度争用放在一边。我建议用 synchronized 开发,直到确实证明 synchronized 不合适,而不要仅仅是假设如果使用 ReentrantLock “性能会更好”。请记住,这些是供高级用户使用的高级工具。(而且,真正的高级用户喜欢选择能够找到的最简单工具,直到他们认为简单的工具不适用为止。)。一如既往,首先要把事情做好,然后再考虑是不是有必要做得更快。

锁的各种分类

在这里插入图片描述

悲观锁/乐观锁

悲观锁:我们假设在多线程使用同一资源时会互相抢占资源,这种态度引起的措施叫悲观锁。悲观锁一般用synchronized或者Lock来加锁。
乐观锁:在使用资源时认为其他资源不会抢占资源,就不用使用加锁的方式,这就是乐观锁,一般使用CAS算法处理。

公平锁/非公平锁

公平锁是指多个线程按照申请锁的顺序来获取锁
非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。有可能,会造成优先级反转或者饥饿现象
对于Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁默认是非公平锁非公平锁的优点在于吞吐量比公平锁大
对于Synchronized而言,也是一种非公平锁。由于其并不像ReentrantLock是通过AQS的来实现线程调度,所以并没有任何办法使其变成公平锁。

可重入锁

可重入锁又名递归锁,是指在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。

synchronized void setA() throws Exception{
    Thread.sleep(1000);
    setB();
}

synchronized void setB() throws Exception{
    Thread.sleep(1000);
}

上面的代码就是一个可重入锁的一个特点,如果不是可重入锁的话,setB可能不会被当前线程执行,可能造成死锁。

独享锁/共享锁

独享锁是指该锁一次只能被一个线程所持有。
共享锁是指该锁可被多个线程所持有。

对于Java ReentrantLock而言,其是独享锁。但是对于Lock的另一个实现类ReadWriteLock,其读锁是共享锁,其写锁是独享锁。
读锁的共享锁可保证并发读是非常高效的,读写,写读 ,写写的过程是互斥的。
独享锁与共享锁也是通过AQS来实现的,通过实现不同的方法,来实现独享或者共享。
对于Synchronized而言,当然是独享锁。

偏向锁/轻量级锁/重量级锁

这三种锁是指锁的状态,并且是针对Synchronized。在Java 5通过引入锁升级的机制来实现高效Synchronized。这三种锁的状态是通过对象监视器在对象头中的字段来表明的。
偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁。降低获取锁的代价。
轻量级锁是指当锁是偏向锁的时候,被另一个线程所访问,偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,提高性能。
重量级锁是指当锁为轻量级锁的时候,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数的时候,还没有获取到锁,就会进入阻塞,该锁膨胀为重量级锁。重量级锁会让其他申请的线程进入阻塞,性能降低。

CAS算法

全名:Compare And Swap(比较与交换)
无锁算法:基于硬件原语实现,在不使用锁(没有线程被阻塞)的清况下实现多线程之间的变量同步。
Jdk中实现:java.util.concurrent包中的原子类(Atomiclnteger)就是通过CAS来实现了乐观锁。
在这里插入图片描述
算法涉及到三个操作数:

需要读写的内存值V
进行比较的值A
要写入的新值B

CAS算法执行过程:两个线程同时操作一个变量他们都会在内存中生成一个副本,首先将原始数据先把参数V赋值给本地参数A,然后比较两个参数A和B,B为要修改后的参数,如果不同则需要修改,此时第一个进程去修改了V值,修改为1,当第二个线程修改时,先进行比较,发现V和A不相同,则成为脏值,程序无法更新值,只能自旋,等待或报错。

自旋锁:在进行完上面的行为后,线程二如果进入自旋,就相当于再把V值读给A,A和B进行比较后,再A和V进行比较,如果A和V相同了,就可以进行交换了。
自旋锁的概念可以描述为当一个线程在获取锁的时候,如果锁已经被其他线程获取,那么该线程就会循环等待,不断判断锁是否被成功获取,自旋直到锁被成功获取才推出循环。需要操作系统切换cpu状态,会耗费一定的时间。
在这里插入图片描述

AQS同步器—AbstractQueuedSynchronizer—抽象队列同步

在这里插入图片描述
此同步器是一个可重入锁

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java面试pdf是一种面试准备资料,用于帮助面试者理解Java编程语言和相关技术。这些pdf通常包含了面试所需的基础知识、常见问题和答案,以及一些具体场景下的实际代码示例。 Java作为一种广泛使用的编程语言,在互联网行业和软件开发领域有很高的需求。因此,很多求职者和招聘者都使用Java面试pdf作为准备和参考资料。 Java面试pdf的好处是它提供了系统的知识框架,能够帮助面试者更好地理解Java编程语言的特点、语法和最佳实践。通过研读这些pdf,面试者可以了解常见的Java面试问题和答案,并提前准备相应的回答,增加面试的成功率。 同时,Java面试pdf还提供了一些实际的问题和答案,例如Java的字符串处理、多线程编程、异常处理等,通过这些实际场景的示例,面试者可以更好地理解Java编程的应用。 然而,Java面试pdf也有一些局限性。它只提供了一种学习和准备的方法,可能无法覆盖所有的面试题目和场景。面试者还需要自己进行更多的练习和深入学习,才能在面试中展现出自己的能力。 总的来说,Java面试pdf是一种辅助学习和准备的工具,它可以帮助面试者更好地理解Java编程语言和相关技术,提高面试的成功率。但面试者还需要自己进行更多的学习和实践,才能在实际面试中获得好的表现。 ### 回答2: Java 面试PDF是指一份电子文档,其中包含了关于Java面试的相关内容。这种PDF常常会被求职者或面试者用于备考和准备面试。它可能包含了面试题目、答案解析、常见问题、技术知识点以及面试技巧等内容。 Java面试PDF对于求职者来说非常重要。它可以帮助求职者了解常见的面试问题,并为他们提供了合适的答案。这样,求职者可以在面试过程中更加自信地回答问题,并展现出对Java编程语言和相关知识的掌握程度。此外,面试官通常也会提问一些深入的技术问题,Java面试PDF可以作为一个良好的学习资源,帮助求职者提前掌握并理解这些技术问题的答案。 然而,Java面试PDF只是备考面试的一种参考工具。它并不能覆盖所有可能出现的问题,也不能保证面试成功。在准备面试时,求职者仍然需要深入研究Java编程语言,并对常见的面试题目和技术问题有所了解。在面试中,除了技术知识外,面试官还会考察求职者的思维能力、解决问题的能力以及团队合作等软技能。 总之,Java面试PDF是一种方便的学习工具,但求职者必须用自己的努力和研究来真正掌握Java编程语言和相关知识,并在面试中展现出自己的能力和潜力。 ### 回答3: Java 面试PDF是一种面试准备材料,通常包含了针对Java开发岗位面试的常见问题和答案。这种PDF可以作为面试者的参考资料,帮助他们更好地了解面试过程和准备面试答案。 Java面试PDF一般会涵盖以下几个方面的问题:Java基础知识、面向对象编程、集合框架、多线程、异常处理、IO流、数据库操作、网络编程、设计模式等等。通过研读这些问题和答案,面试者可以更好地掌握Java开发的核心概念和技术,从而在面试中做出更好的回答。 对于想要准备Java面试的人来说,Java面试PDF是一个非常有用的资源。它不仅可以帮助他们了解常见的面试问题,还可以帮助他们在面试过程中更好地组织自己的回答。此外,通过学习和研究这些问题和答案,他们也可以加深对Java开发的理解和思考。 总之,Java面试PDF是一种有助于面试者准备面试并提升技能的资源。通过利用这些资源,面试者可以更好地应对Java开发岗位的面试并增加自己的竞争力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值