java try lock_ReentrantLock

java try lock_ReentrantLockpackageconcurrent;importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;publicclassTestTryLock{privateListlist=…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

package concurrent;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class TestTryLock {

private List list = new ArrayList();

private Lock lock = new ReentrantLock();

public static void main(String[] args) {

final TestTryLock test = new TestTryLock();

new Thread(“第一个线程 “) {

@Override

public void run() {

test.doSomething(Thread.currentThread());

}

}.start();

new Thread(“第二个线程 “) {

@Override

public void run() {

test.doSomething(Thread.currentThread());

}

}.start();

}

public void doSomething(Thread thread) {

if (lock.tryLock()) {

try {

System.out.println(thread.getName() + “得到了锁.”);

for (int i = 0; i < 10; i++) {

list.add(i);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

System.out.println(thread.getName() + “释放了锁.”);

lock.unlock();

}

} else {

System.out.println(thread.getName() + “获取锁失败.”);

}

}

}

以上代码运行结果如下:

第一个线程 得到了锁.

第一个线程 释放了锁.

第二个线程 得到了锁.

第二个线程 释放了锁.

package concurrent;

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class TestTryLock {

private List list = new ArrayList();

private Lock lock = new ReentrantLock();

public static void main(String[] args) {

final TestTryLock test = new TestTryLock();

new Thread(“第一个线程 “) {

@Override

public void run() {

test.doSomething(Thread.currentThread());

}

}.start();

new Thread(“第二个线程 “) {

@Override

public void run() {

test.doSomething(Thread.currentThread());

}

}.start();

}

public void doSomething(Thread thread) {

if (lock.tryLock()) {

try {

System.out.println(thread.getName() + “得到了锁.”);

for (int i = 0; i < 10; i++) {

list.add(i);

Thread.sleep(10);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

System.out.println(thread.getName() + “释放了锁.”);

lock.unlock();

}

} else {

System.out.println(thread.getName() + “获取锁失败.”);

}

}

}

运行结果如下:

第二个线程 得到了锁.

第一个线程 获取锁失败.

第二个线程 释放了锁.

问题如下:

我知道lock()方法去获取锁,当获取不到锁的时候,会一直等待。直到获取到锁。

tryLock()方法获取锁的时候,制作一次试探,如果获取锁失败,就不会一直等待的。如果是这样的话,如我Demo所示的这样,在业务逻辑中使用tryLock很容易造成程序不可控。比较疑惑这个tryLock的使用方法。。求大神解释。。谢谢~~

回答

这个最好把Lock的四个锁法都比较一下(容我copy些东西):

void lock();

If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired.

在等待获取锁的过程中休眠并禁止一切线程调度

void lockInterruptibly() throws InterruptedException;

If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happens:

The lock is acquired by the current thread; or Some other thread interrupts the current thread, and interruption of lock acquisition is supported.

在等待获取锁的过程中可被中断

boolean tryLock();

Acquires the lock if it is available and returns immediately with the value true. If the lock is not available then this method will return immediately with the value false.

获取到锁并返回true;获取不到并返回false

*boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

If the lock is available this method returns immediately with the value true. If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens:The lock is acquired by the current thread; or Some other thread interrupts the current thread, and interruption of lock acquisition is supported; or The specified waiting time elapses.

在指定时间内等待获取锁;过程中可被中断

假如线程A和线程B使用同一个锁LOCK,此时线程A首先获取到锁LOCK.lock(),并且始终持有不释放。如果此时B要去获取锁,有四种方式:

LOCK.lock(): 此方式会始终处于等待中,即使调用B.interrupt()也不能中断,除非线程A调用LOCK.unlock()释放锁。

LOCK.lockInterruptibly(): 此方式会等待,但当调用B.interrupt()会被中断等待,并抛出InterruptedException异常,否则会与lock()一样始终处于等待中,直到线程A释放锁。

LOCK.tryLock(): 该处不会等待,获取不到锁并直接返回false,去执行下面的逻辑。

LOCK.tryLock(10, TimeUnit.SECONDS):该处会在10秒时间内处于等待中,但当调用B.interrupt()会被中断等待,并抛出InterruptedException。10秒时间内如果线程A释放锁,会获取到锁并返回true,否则10秒过后会获取不到锁并返回false,去执行下面的逻辑。

是否会造成 程序不可控, 不在于这几种方式本身,在于业务类别和使用逻辑上。

为什么说会造成程序不可控呢,调用tryLock方法之后会立即返回结果,根据是否获得锁然后做出相应的业务操作,相比较于lock方法会一直阻塞这本身已经使程序更可控了。

不同的方法有不同的用处啊,只是应用的场景不同,不是不可控

题主这里对程序可控的理解是指每一个任务都按照要求执行,但我觉得既然用tryLock()这个非阻塞的场景,就是要允许某些任务不执行(比如防止重复提交业务),或超时不执行(比如防止资源等待队列溢出)等。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/181567.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • matlab中fprintf函数的用法举例_matlabfopen函数的用法

    matlab中fprintf函数的用法举例_matlabfopen函数的用法fprintf函数在matlab具体应用clcclearage=18;name=’小飞’;fprintf(‘%s的年龄是%d。\n’,name,age)说明:\n表示换行示例clcclearsymsabna=5;b=4;n=30;D(1)=a+b;D(2)=(a+b).^2-a*b;fori=3:nD(i)=D(i-1)*(a+b)-a*b*D(i-2);fprint.

    2022年10月19日
    2
  • PHP接口上传参数返回参数混淆

    PHP接口上传参数返回参数混淆

    2022年2月18日
    36
  • 编译器指令重排和CPU指令重排_十进制调整指令DA怎么用

    编译器指令重排和CPU指令重排_十进制调整指令DA怎么用这个知识点也是很多人说不清道不明的地方,感觉都知道,说又说不出来。为什么会这样呢?因为这几个字,很容易被当成动词去理解,其实正确的理解是当成名词,即指令重排现象。那什么时候会产生指令重排现象呢?两个阶段:1、编译期;2、运行期。编译期指令重排解释型语言是在运行期间执行编译+运行动作,所以运行效率较编译型语言低。Java既可以作为解释型语言去用,也可以作为编译型语言。但是主流的做法是当成编译型语言在…

    2022年10月8日
    2
  • 台式计算机网线,台式电脑如何连接宽带_台式电脑如何连接网线

    台式计算机网线,台式电脑如何连接宽带_台式电脑如何连接网线2017-03-1121:36:28电脑直接拨号上网(有宽带账号和密码)或者自动获取IP(有帐号没密码)上方式设置见图2016-12-1013:29:30右击网上邻居,点属性,创建一个新的连接,按照下一步下一步的步骤就可以了,然后成功之后输入你的宽带号码和密码就可以了,如果你使用的是ASDL拨号的,你可以下一个宽带我世界,电信的话你…2016-12-2917:28:19方法如下1、第一,…

    2022年6月26日
    32
  • 冒泡游戏java_消灭泡泡糖游戏java代码

    冒泡游戏java_消灭泡泡糖游戏java代码对战版

    2022年9月13日
    2
  • geostudio渗流教程_曲面静水压力计算

    geostudio渗流教程_曲面静水压力计算大家好,我是小马老师。本文继续介绍lammps模拟薄膜过滤的案例代码。在前面推文中,已经介绍了模型的建模过程。薄膜建模方法模型经过minimize能量最小化之后,进入弛豫阶段。因弛豫阶段代码较长,不再一一介绍各部分代码的功能,仅对代码中的几个比较重要的功能进行详细介绍。(1)薄膜固定及活塞墙的加压控制在模拟过程中,过滤薄膜不能移动,使用fixsetforce命令对其进行固定。fix mysf1membranesetforce000活塞墙在y、z方向需要固定,在x方向允许移动

    2025年9月23日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号