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()不再赘述。前者主要存在一个等待时间,在测试代码中写入一个等待时间,后者主要是等待中断,会抛出一个中断异常,常用度不高,喜欢探究可以自己深入研究。
以上就是Java 多线程Synchronized和Lock的区别的详细内容,更多关于Java 多线程Synchronized和Lock的资料请关注脚本之家其它相关文章!
相关文章
将ResultSet中得到的一行或多行结果集封装成对象的实例
这篇文章主要介绍了将ResultSet中得到的一行或多行结果集封装成对象的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-05-05
Springboot中@Async异步,实现异步结果合并统一返回方式
这篇文章主要介绍了Springboot中@Async异步,实现异步结果合并统一返回方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-09-09
Java8新特性之Collectors.joining()实例详解
在项目中我们常常要对list集合的数据做一些字符串拼接/处理等相关操作,下面这篇文章主要给大家介绍了关于Java8新特性之Collectors.joining()的相关资料,需要的朋友可以参考下2023-01-01
SpringBoot 下在 yml 中的 logging 日志配置方法
logging 配置主要用于控制应用程序的日志输出行为,可以通过配置定制日志的格式、级别、输出位置等,这篇文章主要介绍了SpringBoot 下在 yml 中的 logging 日志配置,需要的朋友可以参考下2024-06-06
SpringBoot使用AOP+注解实现简单的权限验证的方法
这篇文章主要介绍了SpringBoot使用AOP+注解实现简单的权限验证的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧2019-05-05


最新评论