Java 多线程Synchronized和Lock的区别
作者:zsq_fengchen 发布时间:2023-08-14 11:39:09
标签:Java,多线程,Synchronized,Lock
引言
在多线程中,为了使线程安全,我们经常会使用synchronized和Lock进行代码同步和加锁,但是具体两者有什么区别,什么场景下适合用什么可能还不大清楚,主要的区别大致如下:
区别
1、synchronized是java关键字,而Lock是java中的一个接口
2、synchronized会自动释放锁,而Lock必须手动释放锁
3、synchronized是不可中断的,Lock可以中断也可以不中断
4、通过Lock可以知道线程有没有拿到锁,而synchronized不能
5、synchronized能锁住方法和代码块,而Lock只能锁住代码块
6、Lock可以使用读锁提高多线程读效率
7、synchronized是非公平锁,ReentranLock可以控制是否公平锁
从Lock接口中我们可以看到主要有5个方法,这些方法的功能从注释中可以看出:
lock():获取锁,如果锁被暂用则一直等待
unlock():释放锁
tryLock(): 注意返回类型是boolean,如果获取锁的时候锁被占用就返回false,否则返回true
tryLock(long time, TimeUnit unit):比起tryLock()就是给了一个时间期限,保证等待参数时间
lockInterruptibly():用该锁的获得方式,如果线程在获取锁的阶段进入了等待,那么可以中断此线程,先去做别的事 通过 以上的解释,大致可以解释在上个部分中“锁类型(lockInterruptibly())”,“锁状态(tryLock())”等问题,还有就是前面子所获取的过程我所写的“大致就是可以尝试获得锁,线程可以不会一直等待”用了“可以”的原因。
lock():
public class LockTest {
private Lock lock = new ReentrantLock();
private void method(Thread thread) {
lock.lock();
try {
System.out.println(thread.getName() + " has gotten the lock!");
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(thread.getName() + " has unlocked the lock!");
lock.unlock();
}
}
public static void main(String[] args) {
final LockTest test = new LockTest();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
test.method(Thread.currentThread());
}
}, "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
test.method(Thread.currentThread());
}
}, "t2");
t1.start();
t2.start();
}
}
运行结果:
t1 has gotten the lock!
t1 has unlocked the lock!
t2 has gotten the lock!
t2 has unlocked the lock!
tryLock():
public class LockTest {
private Lock lock = new ReentrantLock();
private void method(Thread thread) {
if (lock.tryLock()) {
lock.lock();
try {
System.out.println(thread.getName() + " has gotten the lock!");
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println(thread.getName() + " has unlocked the lock!");
lock.unlock();
}
} else {
System.out.println("I'm "+thread.getName()+". Someone has gotten the lock!");
}
}
public static void main(String[] args) {
LockTest test = new LockTest();
Thread t1 = new Thread(() -> test.method(Thread.currentThread()), "t1");
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
test.method(Thread.currentThread());
}
}, "t2");
t1.start();
t2.start();
}
}
运行结果:
t1 has gotten the lock!
t1 has unlocked the lock!
I'm t2. Someone has gotten the lock!
看到这里相信大家也都会使用如何使用Lock了吧,关于tryLock(long time, TimeUnit unit)和lockInterruptibly()不再赘述。前者主要存在一个等待时间,在测试代码中写入一个等待时间,后者主要是等待中断,会抛出一个中断异常,常用度不高,喜欢探究可以自己深入研究。
来源:https://www.cnblogs.com/zhaosq/archive/2021/01/04/14202009.html
0
投稿
猜你喜欢
- 归并排序里运用到算法里很重要的一个思想——分治法:将原问题分解为几个规模较小但类似于原问题的子问题——《算法导论》。在每一层递归中都有3个步
- 什么是递归?用Java写一个简单的递归程序递归的定义递归(recursion):以此类推是递归的基本思想,将规模大的问题转化为规模小的问题来
- 1.ArrayList 是基数组结构的,需要连续的内存空间从构造函数可以看出,ArrayList内部用一个Object数组来保存数据。对于无
- JAVA多线程断点下载原理如图:代码如下:import java.io.BufferedReader; import java.io.Fil
- 一、广播机制概述通常情况下在学校的每个教室都会装有一个喇叭,这些喇叭是接入到学校广播室的。如果有重要通知,会发送一条广播来告知全校师生。为了
- JPA是什么? JPA(Java Persistence API)是Sun官方提出的Java持久化规范. 为Java开发人员提供了一种对象/
- 使用开源项目JAVAE 进行视频格式转换JAVAE简介:JAVE (Java音频视频编码器)库是ffmpeg项目的Java包装器。开发人员可
- 经典分布式事务,是相对互联网中的柔性分布式事务而言,其特性为ACID原则,包括原子性(Atomictiy)、一致性(Consistency)
- 一、项目背景1、介绍:最近在springboot项目中需要做一个阿里云OSS图片上传功能点,将OSS图片上传代码提取到公共工具类中,为了方便
- FastJson是阿里开源的一个高性能的JSON框架,FastJson数据处理速度快,无论序列化(把JavaBean对象转化成Json格式的
- 先给大家介绍下Java获取上月份最后一天日期8位。代码如下所示:/** * 获取上个月的最后一天23点59分59
- sqlite是啥?1、一种轻型数据库2、关系型数据库3、占用资源很低,几百K内存,适合嵌入式设备4、支持windows、linux、unix
- 1、研究背景 在当今信息社会发展中中,计算机科
- 本文实例讲述了C#实现多线程下载文件的方法。分享给大家供大家参考。具体实现方法如下:using System;using System.Co
- 【程序1】 题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? 1.程序分析:可填在百位、十位、个位的数字都
- 查询文档 & 基本操作为了方便学习, 本节中所有示例沿用上节的索引按照ID单个GET class_1/_doc/1查询结果:{ &n
- 大体思路如果发总金额为 m的 n 个红包,先用一个长度为 n的临时数组 a 存放 n个随机双精度小数 ,然后用 sum表示数组
- — 遇到问题今天在IDEA里面运行项目的时候报了一个错,如下图所示:— 找到问题根源其实控制台给出的错误信息提示说的很明显:类加载器加载文件
- 前言本文的记录如何用CustomPaint、GestureDetector实现一个进度条控件。首先需要说明的是 flutter Materi
- Spring Data Jpa复杂查询总结只是做一个总结所以就不多说废话了实体类@Entity@Table(name = "t_h