synchronized和lock有什么区别?
一、原始构成
synchronized是关键字属于JVM层面,monitorenter(底层是通过monitor对象来完成,其实wait/notify等方法也依赖monitor对象只有在同步代码块和同步方法中才能调用wait/notify等方法)
Lock是具体的类,是api层面的锁;
二、使用方法
synchronized不需要用户手动释放锁,synchronized代码执行完成以后系统会自动让线程释放对锁的占有
ReentrantLock则需要用户手动去释放锁,若没有主动释放锁,就有可能导致死锁现象。需要使用lock()和unlock()方法配合try finally语句块来完成。
三、等待是否可以中断
synchronized不可中断,除非抛出异常或者正常运行完成。
ReetrantLock可中断,
1. 设置超时方法tryLock(long timeout, TimeUnit unit);
2.lockInterruptibly()放入代码块中,调用interrupt()方法可中断;
四、加锁是否公平
synchronized是非公平锁
ReentrantLock默认是非公平锁,可设置为公平锁。
五、锁绑定多个条件condition
synchronized没有;
ReentrantLock用来实现分组唤醒需要唤醒的线程们,可以精确唤醒,而不是像synchronized要么随机唤醒一个,要么唤醒全部线程。
六、案例
题目:多线程之间按找顺序调用,实现A->B->C三个线程启动,要求如下:
AA打印5次,BB打印10次,CC打印15次,重复上述过程10次.
class ShareResource{
private int number = 1; // A:1, B:2, C:3
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
private Condition conditionC = lock.newCondition();
public void print5(){
try {
lock.lock();
while (number != 1){
conditionA.await();
}
for (int i = 1; i <= 5; i++){
System.out.print("A");
}
System.out.println();
number++;
conditionB.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print10(){
try {
lock.lock();
while (number != 2){
conditionB.await();
}
for (int i = 1; i <= 10; i++){
System.out.print("B");
}
System.out.println();
number++;
conditionC.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void print15(){
try {
lock.lock();
while (number != 3){
conditionC.await();
}
for (int i = 1; i <= 15; i++){
System.out.print("C");
}
System.out.println();
number = 1;
conditionA.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class SynchronizedLockDifference {
public static void main(String[] args) {
ShareResource shareResource = new ShareResource();
new Thread(()->{
for (int i = 1; i <= 10; i++){
shareResource.print5();
}
}, "A").start();
new Thread(()->{
for (int i = 1; i <= 10; i++){
shareResource.print10();
}
}, "B").start();
new Thread(()->{
for (int i = 1; i <= 10; i++){
shareResource.print15();
}
}, "C").start();
}
}
输出结果:
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC
AAAAA
BBBBBBBBBB
CCCCCCCCCCCCCCC Process finished with exit code 0
synchronized和lock有什么区别?的更多相关文章
- synchronized 和 Lock 有什么区别?(未完成)
synchronized 和 Lock 有什么区别?(未完成)
- 用阻塞队列实现一个生产者消费者模型?synchronized和lock有什么区别?
多线程当中的阻塞队列 主要实现类有 ArrayBlockingQueue是一个基于数组结构的有界阻塞队列,此队列按FIFO原则对元素进行排序 LinkedBlockingQueue是一个基于链表结构的 ...
- java面试题之synchronized和lock有什么区别
synchronized和lock的区别: 类别 synchronized lock 存在层次 java的关键字,在jvm层面上 是一个类 锁的释放 1.以获取锁的线程执行完同步代码,释放锁 2.线程 ...
- volatile、synchronized、lock有什么区别,以及在哪些场景下使用哪种方式?
[转]JVM锁机制volatile/synchronized/lock 1.volatile实现原理 (1)聊聊并发(一)——深入分析Volatile的实现原理 --硬件级别锁实现,Lock前缀指令会 ...
- java面试-synchronized与lock有什么区别?
1.原始构成: synchronized是关键字,属于JVM层面,底层是由一对monitorenter和monitorexit指令实现的. ReentrantLock是一个具体类,是API层面的锁. ...
- Java synchronized和 Lock 的区别与用法
在分布式开发中,锁是线程控制的重要途径.Java为此也提供了2种锁机制,synchronized和lock.做为Java爱好者,自然少不了对比一下这2种机制,也能从中学到些分布式开发需要注意的地方. ...
- Synchronized和lock的区别和用法
一.synchronized和lock的用法区别 (1)synchronized(隐式锁):在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要 ...
- synchronized 与 lock 的区别
synchronized 和 lock 的用法区别 synchronized(隐式锁):在需要同步的对象中加入此控制,synchronized 可以加在方法上,也可以加在特定代码块中,括号中表示需要锁 ...
- synchronized和Lock的区别是什么?
原创2020-11-19 11:38:29011024区别:1.lock是一个接口,而synchronized是java的一个关键字.2.synchronized在发生异常时会自动释放占有的锁 ...
随机推荐
- IO 和 NIO 的思考
输入输出是操作系统不可或缺的一部分,大致分为两类:面向磁盘和面向网络.在 Java 中有3种 I/O 类型:BIO.NIO 和 AIO,分别是同步阻塞.同步非阻塞和异步非阻塞 I/O,这里着重描述 B ...
- 利用 Blob 处理 node 层返回的二进制文件流字符串并下载文件
博客地址:https://ainyi.com/65 解释 | 背景 看到标题有点懵逼,哈哈,实际上是后端将文件处理成二进制流,返回到前端,前端处理这个二进制字符串,输出文件或下载 最近公司有个需求是用 ...
- 【网摘】C#.NET 在 MVC 中动态绑定下拉菜单的方法
1. 已知下拉菜单列表项: 在 Controller 控制器类中输入已下代码 1 public class DemoController : Controller 2 { 3 public ...
- 10分钟 在linux里创建.net core helloworld控制台程序
官方教程 安装linux https://www.cnblogs.com/LittleFeiHu/p/9749455.html 第一步 :选择和你本机适用的Linux版本,我这里用的是18.04. 第 ...
- MySQL中SELECT语句简单使用
最近开始复习mysql,查漏补缺吧. 关于mysql 1.MySQL不区分大小写,但是在MySQL 4.1及之前的版本中,数据库名.表名.列名这些标识符默认是区分大小写的:在之后的版本中默认不区分大小 ...
- umijs开发实践-不同页面交叉使用dva中的modal文件导致的错误
最近在使用umijs进行H5开发工作,在开发的过程中踩了一些坑,在这里记录一下. 1:按需加载在现在是很常见的优化方式了,我在.umirc.js中开启dynamicImport后,运行umi buil ...
- 客户端传值里面包含URL特殊字符的应对方法
URL传递值的时候参数里面含有%2f等URL转义问题可通过URLDecoder.decode(字符串,“utf-8”);的方法去转义为"/". 此外:URLEncoder是将字符串 ...
- ext组件中的查询
组件中的查询依赖于组件树,往上可追溯父组件,往下可查找子组件. 组件中的查询主要包括8个方法:up.down.query.child.nextNode.nextSibiling.previoutNod ...
- UE3中Object和Actor的创建与销毁
创建Object ① 在uc脚本中使用new运算符来创建 /********************************************************************** ...
- butterknife使用
butterknife是一个轻量级的DI框架,官网地址:http://jakewharton.github.io/butterknife/ 注意事项:使用前需要对编辑器进行相关设置,详见官网说明. 以 ...