Lock锁,可以得到和 synchronized一样的效果,即实现原子性、有序性和可见性。

相较于synchronized,Lock锁可手动获取锁和释放锁、可中断的获取锁、超时获取锁。

Lock 是一个接口,两个直接实现类:ReentrantLock(重入锁), ReentrantReadWriteLock(读写锁)。

1. 概述

Lock锁,使用时手动获取锁和释放锁,比synchronized更加灵活;可中断的获取锁;超时获取锁。

Lock 锁的基本用法, l.lock()方法进行上锁, l.unlock()方法进行解锁,如下所示。

 Lock l = ...;l.lock(); // 上锁try {// access the resource protected by this lock} finally {l.unlock(); // 解锁}

2. Lock锁的API

修饰符和类型 方法 描述
void lock() 获得锁。
void lockInterruptibly​() 获得锁,可中断。举个例子,当两个线程同时通过lock.lockInterruptibly()想获取某个锁时,假若此时线程A获取到了锁,而线程B只有在等待,那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。
boolean tryLock​() 锁在空闲的才能获取锁(未获得锁不会等待)。举个例子:当两个线程同时通过lock.trylock()想获取某个锁时,假若此时线程A获取到了锁,而线程B不会等待,直接放弃获取锁。
boolean tryLock​(long time, TimeUnit unit)

如果锁定可用,则此方法立即返回值true

如果锁不可用,则当前线程将被禁用以进行线程调度,并且在发生以下三种情况之一之前处于休眠状态:

  • 当前线程获取锁。
  • 其他一些线程中断当前线程。
  • 等待时间过去了,返回false
void unlock​() 释放锁。

3. lock() 方法,unlock()方法

创建一个 Lock 锁:

Lock l = new ReentrantLock();

给代码块上锁:

        l.lock();for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ": ");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}l.unlock();

全部代码:

package lock;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class MyLockStudy implements Runnable {private int count;Lock l = new ReentrantLock();@Overridepublic void run() {l.lock();for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ": ");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}l.unlock();}public static void main(String args[]) {MyLockStudy runn = new MyLockStudy();Thread thread1 = new Thread(runn, "thread1");Thread thread2 = new Thread(runn, "thread2");Thread thread3 = new Thread(runn, "thread3");thread1.start();thread2.start();thread3.start();}
}

运行截图:

4. tryLock()方法

tryLock​(),锁在空闲的才能获取锁(未获得锁不会等待,lock()未获得锁会进入阻塞状态 ),返回值为boolean类型,获取锁则为 true ,反之为 false。

tryLock() 进行加锁:

        if (l.tryLock()) {System.out.println(Thread.currentThread().getName() + "获取锁");for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ": ");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}l.unlock();} else {System.out.println(Thread.currentThread().getName() + "未获取锁");}

完整代码:

package lock;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class MyLockStudy implements Runnable {private int count;Lock l = new ReentrantLock();@Overridepublic void run() {if (l.tryLock()) {System.out.println(Thread.currentThread().getName() + "获取锁");for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ": ");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}l.unlock();} else {System.out.println(Thread.currentThread().getName() + "未获取锁");}}public static void main(String args[]) {MyLockStudy runn = new MyLockStudy();Thread thread1 = new Thread(runn, "thread1");Thread thread2 = new Thread(runn, "thread2");Thread thread3 = new Thread(runn, "thread3");thread1.start();thread2.start();thread3.start();}
}

运行截图如下所示:

5. tryLock​(long time, TimeUnit unit) 方法

如果锁定可用,则此方法立即返回值true。如果锁不可用,则当前线程将被禁用以进行线程调度,并且在发生以下三种情况之一之前处于休眠状态:

  • 当前线程获取锁。
  • 其他一些线程中断当前线程。
  • 等待时间过去了,返回false

设置等待时间为 1000 毫秒。

        try {if (l.tryLock(1000, TimeUnit.MILLISECONDS)) {System.out.println(Thread.currentThread().getName() + "获取锁");for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ": ");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}l.unlock();} else {System.out.println(Thread.currentThread().getName() + "未获取锁");}} catch (InterruptedException e) {e.printStackTrace();}}

完整代码如下所示:

package lock;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class MyLockStudy implements Runnable {private int count;Lock l = new ReentrantLock();@Overridepublic void run() {try {if (l.tryLock(1000, TimeUnit.MILLISECONDS)) {System.out.println(Thread.currentThread().getName() + "获取锁");for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ": ");try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}l.unlock();} else {System.out.println(Thread.currentThread().getName() + "未获取锁");}} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String args[]) {MyLockStudy runn = new MyLockStudy();Thread thread1 = new Thread(runn, "thread1");Thread thread2 = new Thread(runn, "thread2");Thread thread3 = new Thread(runn, "thread3");thread1.start();thread2.start();thread3.start();}
}

运行截图:

如果锁不可用,则当前线程将被禁用以进行线程调度,并且在发生以下三种情况之一之前处于休眠状态,当前线程是可以被中断的。

package lock;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class MyLockStudy implements Runnable {private int count;Lock l = new ReentrantLock();@Overridepublic void run() {try {if (l.tryLock(1000, TimeUnit.MILLISECONDS)) {System.out.println(Thread.currentThread().getName() + "获取锁");for (int i = 0; i <= 500000000; i++) {if (i == 500000000) {System.out.println("运算结束");}}l.unlock();} else {System.out.println(Thread.currentThread().getName() + "未获取锁");}} catch (InterruptedException e) {System.out.println("中断");e.printStackTrace();}}public static void main(String args[]) {MyLockStudy runn = new MyLockStudy();Thread thread1 = new Thread(runn, "thread1");Thread thread2 = new Thread(runn, "thread2");Thread thread3 = new Thread(runn, "thread3");thread1.start();thread2.start();thread3.start();try {TimeUnit.MILLISECONDS.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}thread1.interrupt();thread2.interrupt();thread3.interrupt();}
}

线程1获取了锁,其他线程休眠,然后被中断。

Java 中的Lock锁相关推荐

  1. java中的Lock锁

    一. 概述 Lock 是 java.util.concurrent.locks 包 下的接口,Lock 实现提供了比 synchronized 关键字 更广泛的锁操作,它能以更优雅的方式处理线程同步问 ...

  2. java lock unlock_详解Java中的ReentrantLock锁

    ReentrantLock锁 ReentrantLock是Java中常用的锁,属于乐观锁类型,多线程并发情况下.能保证共享数据安全性,线程间有序性 ReentrantLock通过原子操作和阻塞实现锁原 ...

  3. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等...

    http://blog.51cto.com/13919357/2339446 Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容 ...

  4. Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等

    Java 中15种锁的介绍 在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁 / 非公平锁 可重入锁 / 不可重入锁 独享锁 / 共享锁 互 ...

  5. java volatile lock_Java并发学习笔记 -- Java中的Lock、volatile、同步关键字

    Java并发 一.锁 1. 偏向锁 1. 思想背景 来源:HotSpot的作者经过研究发现,大多数情况下,锁不仅不存在多线程竞争,而且总是由同 一线程多次获得,为了让线程获得锁的代价更低而引入了偏向锁 ...

  6. 浅谈Java中的各种锁

    在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类.介绍的内容如下: 公平锁/非公平锁 可重入锁 独享锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏向锁/轻量级 ...

  7. Java中的各种锁事

    本文来聊下Java中的各种锁 文章目录 锁概述 各种锁描述 本文小结 锁概述 本文来聊下Java中的各种锁,彻底理解Java中的各种锁. Java中的各种锁 序号 锁名称 应用 1 乐观锁 CAS 2 ...

  8. java 自旋锁_搞懂Java中的自旋锁

    轻松搞懂Java中的自旋锁 前言 在之前的文章<一文彻底搞懂面试中常问的各种"锁">中介绍了Java中的各种"锁",可能对于不是很了解这些概念的同学 ...

  9. Java中的互斥锁介绍

    前言   互斥锁是一种广泛应用于多线程编程中的并发控制机制.在Java中,互斥锁有很多不同的实现方式,在本文中我们将介绍Java中常见的几种互斥锁实现方式,并讲解它们的用法.原理和代码案例. sync ...

最新文章

  1. 反编译sencha toucha打包的apk文件,修改应用名称支持中文以及去除应用标题栏
  2. C++中智能指针的设计和使用
  3. 第九章 Django框架——csrf请求伪造和csrf_token使用
  4. 给gridview动态生成radiobutton添加OnCheckedChanged事件
  5. ajax和jsonp
  6. ICS大作业——程序人生 Hello‘s P2P
  7. 如何去掉Delphi自动生成的~.pas等临时文件
  8. PyCharm编辑器的安装
  9. SQLServer left join 出现比左表多的数据
  10. Vue系列(2):Vue 安装
  11. linux daemon 函数,Daemon 进程的创建
  12. 潜龙号开启水下机器人_揭秘我国自主水下机器人“潜龙二号”
  13. 数学笔记30——无穷级数和收敛判定
  14. 【恩智浦杯(飞思卡尔)全国大学生智能汽车竞赛】解读部分北科技术报告图像处理内容(点到为止)
  15. 睦星科技Kolmostar获1000万美元 A 轮融资,将推出更多元的GNSS定位解决方案...
  16. 数据结构分析之线性哈希表(Linear Hash Tables)
  17. linux下架设sendmail邮箱_原理篇
  18. 想自己上线微信小程序一定要会代码?
  19. bat获取系统时间戳
  20. 【职场】反思如何做好技术分分享

热门文章

  1. 利用pymupdf编辑修改pdf
  2. 本地部署你的专属ChatGPT,不用想方设法翻墙了
  3. 外文文献阅读时切忌通读全文,这样做效率翻倍!
  4. 本地计算机上的mysql服务启动后停止,某些服务在未由其他服务或程序使用时将自动停止。
  5. 【Linux 操作系统】Ubuntu 基础操作 基础命令 热键 man手册使用 关机 重启等命令使用
  6. c++调用动态库失败解决办法
  7. Java学习----二维数组排序
  8. oracle-临时表
  9. [GO] Gin入门
  10. 超硬核!MySQL优化从执行计划开始(explain超详细)