原始构成

synchronized是关键字,属于JVM层面

javap -c 的结果显示

synchronized是可重入锁

11:是正常退出 17:是异常退出【保证不产生死锁和底层故障】

Lock是java.util.concurrent.locks包中的一个接口 是API层面的锁

使用方法

synchronized不需要手动释放锁,当synchronized代码执行完后系统自动让线程释放对锁的占用

ReentrantLock则需要用户手动释放没有主动释放的锁,可能出现死锁现象。需要lock、unlock和try/catch一起使用

等待是否可中断

synchronizated不可中断,除非抛出异常或者正常运行完成

reentrantLock可中高端

  • 设置超时方法tryLock 【new ReentrantLock().tryLock(1,TimeUnit.SECONDS);】
  • lockInterruptibly()放代码块中,调用interrupt()方法中断【new ReentrantLock().lockInterruptibly();】

是否是公平锁

synchronizated是非公平锁

reentrantLock源码:默认是非公平锁。也可以传参true为公平锁 false为非公平锁

  1. /**
  2. * Creates an instance of {@code ReentrantLock}.
  3. * This is equivalent to using {@code ReentrantLock(false)}.
  4. */
  5. public ReentrantLock() {
  6. sync = new NonfairSync();
  7. }
  8.  
  9. /**
  10. * Creates an instance of {@code ReentrantLock} with the
  11. * given fairness policy.
  12. *
  13. * @param fair {@code true} if this lock should use a fair ordering policy
  14. */
  15. public ReentrantLock(boolean fair) {
  16. sync = fair ? new FairSync() : new NonfairSync();
  17. }

锁是否绑定多个条件Condition

synchronizated没有,只能随机唤醒一个(notify()),或者唤醒全部唤醒(notifyAll())

ReentrantLock用来实现分组唤醒需要唤醒的线程,可以精确唤醒某个线程。

例如:多线程之间按顺序调用 实现线程之间按顺序启动【精确唤醒的举例】

  1. import java.util.concurrent.locks.Condition;
  2. import java.util.concurrent.locks.Lock;
  3. import java.util.concurrent.locks.ReentrantLock;
  4.  
  5. /**
  6. * 一个拍照的景点 有3个人要按顺序排单人照
  7. * 张三想要拍1张 李四想要拍3张 王五想要拍5张
  8. * 他们按照这个顺序排了两个景点
  9. */
  10. class Plat{
  11. private int id = 1; // 3人的编号
  12. private Lock lock = new ReentrantLock();
  13. private Condition person1 = lock.newCondition();
  14. private Condition person2 = lock.newCondition();
  15. private Condition person3 = lock.newCondition();
  16. public void person1TakePhoto(){
  17. lock.lock();
  18. try{
  19. while (id != 1){
  20. person1.await();
  21. }
  22. for (int i = 0; i < 1; i++) {
  23. System.out.println(Thread.currentThread().getName()+ "拍了"+(i+1)+"张照片");
  24. }
  25. id = 2;
  26. person2.signal();
  27. }catch(Exception e){
  28. e.printStackTrace();
  29. }finally{
  30. lock.unlock();
  31. }
  32. }
  33. public void person2TakePhoto(){
  34. lock.lock();
  35. try{
  36. while (id != 2){
  37. person2.await();
  38. }
  39. for (int i = 0; i < 3; i++) {
  40. System.out.println(Thread.currentThread().getName()+ "拍了"+(i+1)+"张照片");
  41. }
  42. id = 3;
  43. person3.signal();
  44. }catch(Exception e){
  45. e.printStackTrace();
  46. }finally{
  47. lock.unlock();
  48. }
  49. }
  50. public void person3TakePhoto(){
  51. lock.lock();
  52. try{
  53. while (id != 3){
  54. person3.await();
  55. }
  56. for (int i = 0; i < 5; i++) {
  57. System.out.println(Thread.currentThread().getName()+ "拍了"+(i+1)+"张照片");
  58. }
  59. id = 1;
  60. person1.signal();
  61. }catch(Exception e){
  62. e.printStackTrace();
  63. }finally{
  64. lock.unlock();
  65. }
  66. }
  67.  
  68. }
  69. public class ReentantLockTest {
  70. public static void main(String[] args) throws InterruptedException {
  71. Plat plat = new Plat();
  72. new Thread(()->{
  73. for (int i = 0; i < 2; i++) {
  74. plat.person1TakePhoto();
  75. }
  76. },"张三").start();
  77. new Thread(()->{
  78. for (int i = 0; i < 2; i++) {
  79. plat.person2TakePhoto();
  80. }
  81. },"李四").start();
  82. new Thread(()->{
  83. for (int i = 0; i < 2; i++) {
  84. plat.person3TakePhoto();
  85. }
  86. },"王五").start();
  87. }
  88. }

输出结果:

  1. 张三拍了1张照片
  2. 李四拍了1张照片
  3. 李四拍了2张照片
  4. 李四拍了3张照片
  5. 王五拍了1张照片
  6. 王五拍了2张照片
  7. 王五拍了3张照片
  8. 王五拍了4张照片
  9. 王五拍了5张照片
  10. 张三拍了1张照片
  11. 李四拍了1张照片
  12. 李四拍了2张照片
  13. 李四拍了3张照片
  14. 王五拍了1张照片
  15. 王五拍了2张照片
  16. 王五拍了3张照片
  17. 王五拍了4张照片
  18. 王五拍了5张照片

【JUC】synchronizated和lock的区别&新lock的优势的更多相关文章

  1. 第44天学习打卡(JUC 线程和进程 并发和并行 Lock锁 生产者和消费者问题 如何判断锁(8锁问题) 集合类不安全)

    什么是JUC 1.java.util工具包 包 分类 业务:普通的线程代码 Thread Runnable 没有返回值.效率相比Callable相对较低 2.线程和进程 进程:一个程序.QQ.exe, ...

  2. 详解synchronized与Lock的区别与使用

    知识点 1.线程与进程 在开始之前先把进程与线程进行区分一下,一个程序最少需要一个进程,而一个进程最少需要一个线程.关系是线程–>进程–>程序的大致组成结构.所以线程是程序执行流的最小单位 ...

  3. 锁、C#中Monitor和Lock以及区别

    1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取锁之后因为异常,致锁 ...

  4. C#知识点总结系列:4、C#中Monitor和Lock以及区别

    Monitor对象 1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取 ...

  5. C#中Monitor和Lock以及区别

    Monitor对象 1.Monitor.Enter(object)方法是获取锁,Monitor.Exit(object)方法是释放锁,这就是Monitor最常用的两个方法,当然在使用过程中为了避免获取 ...

  6. hibernate中load,get;find,iterator;merge,saveOrUpdate,lock的区别

    hibernate中load,get;find,iterator;merge,saveOrUpdate,lock的区别 转自http://www.blogjava.net/bnlovebn/archi ...

  7. Java中synchronized和Lock的区别

    synchronized和Lock的区别synchronize锁对象可以是任意对象,由于监视器方法必须要拥有锁对象那么任意对象都可以调用的方法所以将其抽取到Object类中去定义监视器方法这样锁对象和 ...

  8. 【Java】synchronized与lock的区别

    从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式来实现同步访问,那就是Lock. 也许有朋友会问,既然都可以通过synchronized来实现同步访问了 ...

  9. Synchronize 和 Lock 的区别与用法

    一.synchronized和lock的用法区别 (1)synchronized(隐式锁):在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要 ...

随机推荐

  1. matlab混合编程向导(vc,vb,.net...)

    一.matlab与vc混编  1.通过mcc将matlab的m文件转化为cpp,c文件或dll供vc调用:     这方面的实现推荐精华区Zosco和ljw总结的方法(x-6-1-4-3-1和2)  ...

  2. 基于国内某云的 Domain Fronting 技术实践

    发布时间:2019-12-16 11:30:53 一.简介 Domain Fronting,中文译名 “域前置” 或 “域名前置”,是一种用于隐藏真实C2服务器IP且同时能伪装为与高信誉域名通信的技术 ...

  3. GCD-Euclidean Algorithm

    求解两个正整数的最大公约数(Greatest Common Devisor),可以采用循环进行遍历,不过效率很低.所以引入欧几里得算法(Euclid's algorithm). 欧几里得算法基于GCD ...

  4. win7乱码问题解决方法(cmd变小,plsql客户端乱码)

    1.点击控制面板:时钟.语言和区域:区域和语言:管理点击更改系统区域设置,选中英语(英国):重启 2.点击控制面板:时钟.语言和区域:区域和语言:管理点击更改系统区域设置,选中中文(简体,中国):重启 ...

  5. 详解十大经典数据挖掘算法之——Apriori

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题的第19篇文章,我们来看经典的Apriori算法. Apriori算法号称是十大数据挖掘算法之一,在大数据时代威风无两,哪 ...

  6. LateX的简单字体设置(颜色,居中,大小等)

    \(\color{red}{Ⅰ.文本单行居中}\) $$\text{我是蒟蒻}$$ \[\text{我是蒟蒻} \] \(\color{Black}{Ⅱ.设置字体颜色}\) $$\color{Purp ...

  7. spring的后台数据校验

    数据校验对于开发项目来说是必须的.校验一般分为前台校验和后台校验,前台校验是必须要做的,后台校验是可选的.后台校验相对前台校验来说配置起来一般更复杂.前台校验通过js做,前台校验一般非常容易绕过.sp ...

  8. java结合email实现自动推送

    1.获取表中最后一条数据 public static String demo() throws SQLException { String sql = "select * FROM baox ...

  9. Vue + Element-ui实现后台管理系统(1) --- 总述

    总述 一.项目效果  整体效果 登陆页 后台首页 用户管理页 说明 这里所有的数据都不是直接通过后端获取的, 而是通过Mock这个工具来模拟后端返回的接口数据. 附上github地址: mall-ma ...

  10. python是如何进行参数传递的?

    在分析python的参数传递是如何进行的之前,我们需要先来了解一下,python变量和赋值的基本原理,这样有助于我们更好的理解参数传递. python变量以及赋值 数值 从几行代码开始 In [1]: ...