Java面试之synchronized和Lock有什么区别?
1.原始构成
synchronized是关键字,属于JVM层面
monitorenter,monitorexit(底层是通过monitor对象来完成,其实wait/notify等方法也依赖于monitor对象,只有在同步块或方法中才能调用wait/notify等方法)Lock是具体类(java.util.concurrent.locks.lock)是api层面的锁。java5开始使用。
2.使用方法
synchronized 不需要用户手动去释放锁,当synchronized代码执行完成后系统会自动让线程释放对锁的占用。
ReentrantLock 则需要用户去手动释放锁,若没有主动释放,就会导致出现死锁现象。
需要lock()和unlock()方法配合try/finally语句块来完成。
3.等待是否可中断
- synchronized 不可中断,除非抛出异常或者正常运行完成。
- ReentrantLock 可中断,
- 1.设置超时方法 tryLock(long timeout, TimeUnit unit);
- 2.lockInterruptibly()放代码块中,调用interrupt方法可中断。
4.加锁是否公平
- synchronized 非公平锁
- ReentrantLock
两者都可以,默认非公平锁,构造方法可以传入boolean值,true为公平锁,false为非公平锁。
5.锁绑定多个条件Condition
- synchronized没有
- ReentrantLock 用来实现分组唤醒,需要唤醒的线程们,可以精准唤醒,而不是像synchronized要么随机唤醒一个,要么唤醒全部线程。
我们来做一道题,具体了解一下
题目:多线程之家按顺序调用,实现A->B->C三个线程启动,需求如下:
A打印5次,B打印10次,C打印15次
紧接着
A打印5次,B打印10次,C打印15次
…
来10轮
话不多说,上代码:
package BlockingQueue;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class MyResource {private int number = 1; //1:线程A 2:线程B 3:线程Cprivate Lock lock = new ReentrantLock();private Condition c1 = lock.newCondition();private Condition c2 = lock.newCondition();private Condition c3 = lock.newCondition();public void print5(){lock.lock();try {//判断while (number !=1){c1.await();}//干活 打印5次for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}//改变标志位的值,多线程中很重要number = 2;//通知c2.signalAll();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}public void print10(){lock.lock();try {//判断while (number !=2){c2.await();}//干活 打印10次for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}//改变标志位的值,多线程中很重要number = 3;//通知c3.signalAll();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}public void print15(){lock.lock();try {//判断while (number !=3){c3.await();}//干活 打印15次for (int i = 0; i < 15; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}//改变标志位的值,多线程中很重要number = 1;//通知c1.signalAll();}catch (Exception e){e.printStackTrace();}finally {lock.unlock();}}}
public class SyncAndReentrantLockDemo {public static void main(String[] args) {MyResource myResource = new MyResource();new Thread(() -> {for (int i = 0; i < 10; i++) {myResource.print5();}},"A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {myResource.print10();}},"B").start();new Thread(() -> {for (int i = 0; i < 10; i++) {myResource.print15();}},"C").start();}
}
执行结果:
"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:D:\software\idea\IntelliJ IDEA 2020.3.1\lib\idea_rt.jar=53196:D:\software\idea\IntelliJ IDEA 2020.3.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_131\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_131\jre\lib\rt.jar;D:\idea-workspace-all\juc\out\production\juc" BlockingQueue.SyncAndReentrantLockDemo
A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
C 0
C 1
C 2
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 12
C 13
C 14
A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
C 0
C 1
C 2
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 12
C 13
C 14
A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
C 0
C 1
C 2
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 12
C 13
C 14
A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
C 0
C 1
C 2
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 12
C 13
C 14
A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
C 0
C 1
C 2
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 12
C 13
C 14
A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
C 0
C 1
C 2
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 12
C 13
C 14
A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
C 0
C 1
C 2
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 12
C 13
C 14
A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
C 0
C 1
C 2
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 12
C 13
C 14
A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
C 0
C 1
C 2
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 12
C 13
C 14
A 0
A 1
A 2
A 3
A 4
B 0
B 1
B 2
B 3
B 4
B 5
B 6
B 7
B 8
B 9
C 0
C 1
C 2
C 3
C 4
C 5
C 6
C 7
C 8
C 9
C 10
C 11
C 12
C 13
C 14Process finished with exit code 0
Java面试之synchronized和Lock有什么区别?相关推荐
- Synchronized和Lock有什么区别
前言 早期的时候我们对线程的主要操作为: synchronized wait notify 然后后面出现了替代方案 lock await singal 问题 synchronized 和 lock 有 ...
- Java面试之synchronized的前世今生
文章目录 synchronized原理 实现原理 锁优化 偏向锁 获得锁 撤销锁 轻量级锁 加锁 解锁 重量级锁 其他优化 自旋锁与自适应自旋锁 锁消除 锁粗化 锁的优缺点对比 synchronize ...
- Java 锁机制(synchronized 与 Lock)
在java中,解决同步问题,很多时候都会使用到synchronized和Lock,这两者都是在多线程并发时候常使用的锁机制. synchronized是java中的一个关键字,也就是说是java内置的 ...
- Java面试之Synchronized无法禁止指令重排却能保证有序性
为什么Synchronized无法禁止指令重排,却能保证有序性 前言 首先我们要分析下这道题,这简单的一个问题,其实里面还是包含了很多信息的,要想回答好这个问题,面试者至少要知道一下概念: Java内 ...
- java面试 内存中堆和栈的区别
java中的内存,分为两种,一为堆内存,二为栈内存. 栈内存 在函数中定义的基本类型的变量和对象的引用变量都是在函数的栈内存中分配. 当在一段代码块中声明了一个变量时,java就会在栈内存中为这个变量 ...
- Java面试--堆和栈的概念和区别
堆和栈的概念和区别[转载自博客] 在说堆和栈之前,我们先说一下JVM(虚拟机)内存的划分: Java程序在运行时都要开辟空间,任何软件在运行时都要在内存中开辟空间,Java虚拟机运行时也是要开辟空间的 ...
- 精通Java 面试 07题 接口和抽象类的区别 (持续更新中)
文章目录 一.接口和抽象类的区别(方式一) 二.接口和抽象类的区别(方式二) 总结 这里我写了两种回答方式,可以各取所需. 一.接口和抽象类的区别(方式一) 抽象类可以存在普通成员函数,而接口只能存在 ...
- java面试必会题——==与equals的区别
一.先从表面层次来看==和equals的区别, 一个是运算符,一个是方法 二."==" 单独拿出来看,==如果比较的是基本数据类型,那么判断的就是数值 ==如果拿来比较的是引用数据 ...
- Java 面试如何坐等 offer?
2015 年,因为工作岗位的变动,开始负责给集团招聘一些技术人员,出于对公司的负责,也为了更好的胜任技术经理的职位,在面试的这件事上,我做了大量的"功课",首先我研究了几乎所有大厂 ...
最新文章
- iOS Public Beta 5值得关注的7个变化
- You have new mail
- virtualenvwrapper 的安装和使用
- Android仿微信高效压缩图片(libjpeg)
- Linux最全命令详解,请记下来!
- jax-rs jax-ws_在JAX-RS中处理异步请求中的超时
- c++ hsv 红色范围_维生素C的定量测定—2,6二氯酚靛酚法
- 未能加载文件或程序集“Newtonsoft.Json”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040)
- CUDA 多GPU调用实现
- ICPC North Central NA Contest 2017 E - Is-A? Has-A? Who Knowz-A?
- 阿里P7级别面试经验总结,完整版开放下载
- php判断是否夏令时,关于php:时区和夏令时问题
- 分布式文件存储FASTDFS
- NANK南卡降噪耳机和OPPO蓝牙耳机哪个更好呢?哪款更能打?
- 照片后期-lightroom常用调色常见参数解
- iar升级芯片库_【经验】如何使用IAR生成MCU RL78的库文件?
- 企业微信CRM管理系统的优势
- 语音转文字转换器怎么用,免费的语音转文字方法介绍
- Java String 格式化示例
- 用递归的方式分析白色相簿2 coda篇各结局概率