Lock接口
本文最后更新于46 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

锁主要是用来控制多个现成访问共享变量的方式,在Lock接口出现之前,Java主要是靠Synchronized关键字来实现锁功能,在Lock接口出现后,他能实现Synchronized关键字类似的同步功能。

Lock的使用:

 Lock lock = new ReetrantLock();
    lock.lock();
    try{
    } finally {
        lock.unlock();
    }
  • 解锁过程放入finally块能确保锁能被释放
  • 加锁过程不要写在try里,因为加锁如果发生异常,也会进入finally块导致锁无故释放
  • 此外,Lock的API还提供了tryLock():上市非阻塞的获取锁,成功放回true,失败返回false

 

Lock对比Synchronized:

相同点:

  • 都是用来保证资源线程安全的
  • 都可以保证可见性
  • Synchronized和ReentrantLock都拥有可重入的特点。

不同点:

  • 加解锁控制区别:Synchronized关键字的加锁和解锁都是由JVM控制的,是自动的,而Lock的加锁解锁都要手动控制,一般会把unlock()操作放在finally块中,以防忘记解锁。
  • 灵活性:Synchronized在一个线程获取锁之后,其他线程想要获取锁只能等待,在升级到重量级锁后线程只能进入阻塞队列,直到尺有所的线程释放这个锁。Lock可以使用lockInterruptibly方法,不想等了可以中断退出,也可以使用trylock方法获取锁,成功则获取,失败则可以先去干别的事情。总结来说Lock更加灵活。
  • Synchronized锁同时只有被一个线程持有,而Lock可以没有这个限制,比如读写锁中的读锁可以被多个现成同时持有
  • Synchronized是非公平锁(一个线程在尝试获取锁时会不断自旋尝试获取锁,只有在获取一定次数仍未获取才会进入AQS队列排队获取锁)。而Lock锁可以实现公平锁也能实现非公平锁。
  • Synchronized获取锁失败会进入Blocked状态。而Lock(非trylock方法)获取锁失败会进入Waiting或者Timed_Waiting状态

 

如何选择Synchronized和Lock?

  • 如果能既不使用Lock也不使用Synchronized,那么就少使用,因为许多情况下可以使用java.util.concurrent包的的类,比如ExecutorService、ConCurrentHashMap等不需要我们控制加锁解锁的类
  • 如果Synchronized关键字适合你的项目,那么尽量使用Synchronized,因为这样可以减少代码编写的数量,减少出错,因为如果忘记在finally块里解锁,代码可能会出很大的问题,因此Synchronized更安全
  • 如果需要实现特殊的场景,如尝试锁、公平锁、可中断锁、多线程持有锁等,才使用Lock
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇