前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Synchronized和Lock

Synchronized和Lock

原创
作者头像
在下是首席架构师
发布2022-08-03 14:26:52
2460
发布2022-08-03 14:26:52
举报
文章被收录于专栏:从入门到出门从入门到出门
锁的优化

Lock没有引入锁的升级这个概念,只有普通的自旋和偏向锁 synchronized 拥有锁的升级,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁 等技术来减少锁操作的开销。并且还会随着竞争的激烈而逐渐升级

可中断

synchronized 是不可以被中断的,但Lock是可以中断它的,Lock中断的代码见下方:

代码语言:javascript
复制
package com.example.demo;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 使用ReentrantLock还可以调用lockInterruptibly方法,可以对线程interrupt方法做出响应,
 * 在一个线程等待锁的过程中,可以被打断
 */
public class 中断锁 {

    public static void main(String[] args) {
        Lock lock = new ReentrantLock();

        Thread t1 = new Thread(() -> {
            try {
                lock.lock();
                System.out.println("t1 start");
                TimeUnit.SECONDS.sleep(5000);
                System.out.println("t1 end");
            } catch (InterruptedException e) {
                System.out.println("t1 interrupted!");
            } finally {
                lock.unlock();
            }
        });
        t1.start();

        Thread t2 = new Thread(() -> {
            try {
                //lock.lock();
                lock.lockInterruptibly(); //可以对interrupt()方法做出响应
                System.out.println("t2 start");
                TimeUnit.SECONDS.sleep(5000);
                System.out.println("t2 end");
            } catch (InterruptedException e) {
                System.out.println("t2 interrupted!");
            } finally {
                lock.unlock();
            }
        });
        t2.start();

        t1.interrupt(); //打断线程1的等待,无法打断,因为线程1是.lock()方法
        t2.interrupt(); //打断线程2的等待,可以打断,因为线程2是.lockInterruptibly()方法

    }
}
公平锁

Lock支持公平锁,synchronized 不支持公平锁

Lock支持更多场景

ReentrantReadWriteLock:可以对于读或者写进行自定义的锁 private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); //读锁 private final Lock w = rwl.writeLock(); //写锁 synchronized 锁只能同时被一个线程拥有,但是 Lock 锁没有这个限制 例如在读写锁中的读锁,是可以同时被多个线程持有的,可是 synchronized 做不到

应该选择synchronized还是应该选择Lock?

  • 如果能不用最好既不使用 Lock 也不使用 synchronized。因为在许多情况下你可以使用 java.util.concurrent 包中的机制,它会为你处理所有的加锁和解锁操作,也就是推荐优先使用工具类来加解锁
  • 如果 synchronized 关键字适合你的程序, 那么请尽量使用它,这样可以减少编写代码的数量,减少出错的概率。因为一旦忘记在 finally 里 unlock,代码可能会出很大的问题,而使用 synchronized 更安全
  • 如果特别需要 Lock 的特殊功能,比如尝试获取锁、可中断、超时功能等,才使用 Lock

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 应该选择synchronized还是应该选择Lock?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档