Lock

news/2024/11/28 4:16:50/

lock接口

Lock lock = ...;
lock.lock();
try{//处理任务
}catch(Exception ex){
}finally{lock.unlock();   //释放锁
}

经常这样使用

Lock lock = ...;
if(lock.tryLock()) {try{//处理任务}catch(Exception ex){}finally{lock.unlock();   //释放锁} 
}else {//如果不能获取锁,则直接做其他事情
}

lock()方法

ReentrantLockLock接口的一个实现类,意思是“可重入锁”,接下来我们通过一个例子来学习lock()方法的正确使用方式。

因为Lock是一个接口所以我们在编程时一般会使用它的实现类,ReentrantLockLock接口的一个实现类,意思是“可重入锁”,接下来我们通过一个例子来学习lock()方法的正确使用方式。

示例1:

public class Test {private ArrayList<Integer> arrayList = new ArrayList<Integer>();public static void main(String[] args)  {final Test test = new Test();new Thread(){public void run() {test.insert(Thread.currentThread());};}.start();new Thread(){public void run() {test.insert(Thread.currentThread());};}.start();}  public void insert(Thread thread) {Lock lock = new ReentrantLock();    //注意这个地方lock.lock();try {System.out.println(thread.getName()+"得到了锁");for(int i=0;i<5;i++) {arrayList.add(i);}} catch (Exception e) {// TODO: handle exception}finally {System.out.println(thread.getName()+"释放了锁");lock.unlock();}}
}

输出:

Thread-1得到了锁` `Thread-0得到了锁` `Thread-0释放了锁` `Thread-1释放了锁

结果可能出乎你的意料,不对呀,按道理应该是一个线程得到锁其他线程不能获取锁了的啊,为什么会这样呢?是因为insert()方法中lock变量是一个局部变量。THread-0Thread-1获取到的是不同的锁,这样不会造成线程的等待。

那怎么才能利用lock()实现同步呢?相信你已经想到了,只要将Lock定义成全局变量就可以了。

public class Test {private ArrayList<Integer> arrayList = new ArrayList<Integer>();private Lock lock = new ReentrantLock();    //注意这个地方public static void main(String[] args)  {final Test test = new Test();new Thread(){public void run() {test.insert(Thread.currentThread());};}.start();new Thread(){public void run() {test.insert(Thread.currentThread());};}.start();}  public void insert(Thread thread) {lock.lock();try {System.out.println(thread.getName()+"得到了锁");for(int i=0;i<5;i++) {arrayList.add(i);}} catch (Exception e) {// TODO: handle exception}finally {System.out.println(thread.getName()+"释放了锁");lock.unlock();}}
}

结果:

Thread-0得到了锁` `Thread-0释放了锁` `Thread-1得到了锁` `Thread-1释放了锁

这样就是我们预期的结果了。

很多时候我们为了提高程序的效率不希望线程为了等待锁而一直阻塞,这个时候可以使用tryLock()可以达到目的。

示例,将之前的insert()方法修改成tryLock()实现:

 public void insert(Thread thread) {if(lock.tryLock()) {try {System.out.println(thread.getName()+"得到了锁");for(int i=0;i<5;i++) {arrayList.add(i);}} catch (Exception e) {// TODO: handle exception}finally {System.out.println(thread.getName()+"释放了锁");lock.unlock();}} else {System.out.println(thread.getName()+"获取锁失败");}
}

输出:

Thread-0得到了锁` `Thread-1获取锁失败` `Thread-0释放了锁

http://www.ppmy.cn/news/903627.html

相关文章

转载好用的小工具 【who-lock-me】

Google搜索&#xff1a;who-lock-me http://www.dr-hoiby.com/WhoLockMe/ 安装后右键进程就可知道文件被什么调用了 WhoLockMe Explorer Extension v2.0 beta (NT-Win2K-XP) To download this freeware WhoLockMe200.zip(23KB) Dr. Hoiby is the author of this little to…

如何删除被锁定的文件(一)他山工具篇 WhoLockMe?

在删除Windows文件时&#xff0c;大家经常会遇到如图1这样的对话框&#xff0c;而且Windows也并未提示到底是哪个进程占用了该文件&#xff0c;所以每每到这个时候大家都会感到束手无策。最近&#xff0c;笔者找到了一个解决这个问题的非常好的一个小工具WhoLockMe。这个小工具…

RocketMQ 源码编译部署包

1. 版本 Java 版本: 1.8.0_201 RocketMQ 版本: 5.1.3 2.打包 git clone https://github.com/apache/rocketmq.git git checkout release-5.1.3 cd rocketmq 2.1 编译子模块 jar 包&#xff0c;编译一次 9 分钟左右 mvn clean package -DskipTests cd ${子模块名称}/target/2.…

C# Modbus通信从入门到精通(4)——Modbus RTU(0x02功能码)

1、02(0x02)读线圈输入 使用该功能码能从远程地址中读取1到2000个输入线圈的状态,每个线圈的状态只能是0或者1,读取的线圈数量由主站读取时指定。 2、发送报文格式 更详细的格式如下: 从站地址+功能码+起始地址高位+起始地址低位+线圈数量高位+线圈数量低位+CRC,一共8个…

活泼的小娃娃

目测娃娃三岁&#xff0c;在地铁上转来转去&#xff0c;很活泼&#xff0c;今天这个时候车上人不多&#xff0c;小娃娃走来走去&#xff0c;他家大人叫他回来坐到怀里&#xff0c;他不听也不愿意。大人瞪眼训他&#xff0c;他嘿嘿笑笑继续走来走去自己玩&#xff0c;再后来围着…

天堂avatar

2010年2月2日晚上12看完期待已久的AVATAR&#xff0c;普通3D。说实在的&#xff0c;没有预想中的那么好&#xff0c;可能是由于过于期待导致要求太高的缘故。影片故事比较俗套&#xff0c;一如既往的美式英雄主义&#xff0c;最后一分钟力挽狂澜。但想想它毕竟是一部商业片&…

gt包的诱惑

引言 今天在地铁上&#xff0c;逛 Rweekly 的时候&#xff0c;不小心翻到 gt 包&#xff0c;真的是诱惑人&#xff01; gt在studio中的介绍 看到介绍中的图片&#xff0c;不自主的赞叹作者的思考力&#xff01;这也让我联想到配合 rmarkdown、tidyverse、ggplot2 等我常用的…

当充气娃娃过于逼真......

1 朋友一生一起走.... ▼ 2 总裁爹是被吓到了吗&#xff1f; ▼ 3 我宣布&#xff1a;本届舞林大会&#xff0c;冠军已出&#xff01; ▼ 4 哥哥&#xff0c;我来了&#xff01; ▼ 5 为了防疫&#xff0c;泰国的小朋友们很不容易 ▼ 6 这位爸爸真的是非常巧妙了&a…