精华内容
下载资源
问答
  • package concurrent;import java.util.ArrayList;...import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class TestTryLock {private List list =...

    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()这个非阻塞的场景,就是要允许某些任务不执行(比如防止重复提交业务),或超时不执行(比如防止资源等待队列溢出)等。

    展开全文
  • package concurrent;import java.util.ArrayList;...import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class TestTryLock {private List list =...

    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的使用方法。。求大神解释。。谢谢~~

    展开全文
  • tryLock方法试图申请一个锁,在成功获得锁后返回true,否则,立即返回false,而且线程可以立即离开去做其他事。可以调用tryLock时,使用超时参数。lock方法不能被中断。如果一个线程在等待获得一个锁时被中断,中断...

    线程在调用lock方法来获得另一个线程所持有的锁的时候,很可能发生阻塞。应该更加谨慎地申请锁。tryLock方法试图申请一个锁,在成功获得锁后返回true,否则,立即返回false,而且线程可以立即离开去做其他事。

    可以调用tryLock时,使用超时参数。

    lock方法不能被中断。如果一个线程在等待获得一个锁时被中断,中断线程在获得锁之前一直处于阻塞状态。如果出现死锁,那么,lock方法就无法终止。

    API介绍:

    Lock接口

    1、tryLock

    boolean tryLock()

    仅在调用时锁为空闲状态才获取该锁。

    如果锁可用,则获取锁,并立即返回值 true。如果锁不可用,则此方法将立即返回值 false。

    此方法的典型使用语句如下:Lock lock = ...;      if (lock.tryLock()) {          try {

    // manipulate protected state

    } finally {

    lock.unlock();

    }

    } else {

    // perform alternative actions

    }12345678910

    此用法可确保如果获取了锁,则会释放锁,如果未获取锁,则不会试图将其释放。

    返回:

    如果获取了锁,则返回 true;否则返回 false。

    2、tryLock

    boolean tryLock(long time,

    TimeUnit unit)

    throws InterruptedException

    如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。

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

    锁由当前线程获得;或者

    其他某个线程中断当前线程,并且支持对锁获取的中断;或者

    已超过指定的等待时间

    如果获得了锁,则返回值 true。

    如果当前线程:

    在进入此方法时已经设置了该线程的中断状态;或者

    在获取锁时被中断,并且支持对锁获取的中断,

    则将抛出 InterruptedException,并会清除当前线程的已中断状态。

    如果超过了指定的等待时间,则将返回值 false。如果 time 小于等于 0,该方法将完全不等待。

    实现注意事项

    在某些实现中可能无法中断锁获取,即使可能,该操作的开销也很大。程序员应该知道可能会发生这种情况。在这种情况下,该实现应该对此进行记录。

    相对于普通方法返回而言,实现可能更喜欢响应某个中断,或者报告出现超时情况。

    Lock 实现可能可以检测锁的错误用法,例如,某个调用可能导致死锁,在特定的环境中可能抛出(未经检查的)异常。该 Lock 实现必须对环境和异常类型进行记录。

    参数:

    time - 等待锁的最长时间

    unit - time 参数的时间单位

    返回:

    如果获得了锁,则返回 true;如果在获取锁前超过了等待时间,则返回 false

    抛出:

    InterruptedException - 如果在获取锁时,当前线程被中断(并且支持对锁获取的中断)

    3、lockInterruptibly

    void lockInterruptibly()

    throws InterruptedException

    如果当前线程未被中断,则获取锁。

    如果锁可用,则获取锁,并立即返回。

    如果锁不可用,出于线程调度目的,将禁用当前线程,并且在发生以下两种情况之一以前,该线程将一直处于休眠状态:

    锁由当前线程获得;或者

    其他某个线程中断当前线程,并且支持对锁获取的中断。

    如果当前线程:

    在进入此方法时已经设置了该线程的中断状态;或者

    在获取锁时被中断,并且支持对锁获取的中断,

    则将抛出 InterruptedException,并清除当前线程的已中断状态。

    实现注意事项

    在某些实现中可能无法中断锁获取,即使可能,该操作的开销也很大。程序员应该知道可能会发生这种情况。在这种情况下,该实现应该对此进行记录。

    相对于普通方法返回而言,实现可能更喜欢响应某个中断。

    Lock 实现可能可以检测锁的错误用法,例如,某个调用可能导致死锁,在特定的环境中可能抛出(未经检查的)异常。该 Lock 实现必须对环境和异常类型进行记录。

    抛出:

    InterruptedException - 如果在获取锁时,当前线程被中断(并且支持对锁获取的中断)。

    展开全文
  • Java多线程:tryLock()方法tryLock(long time, TimeUnit unit) 的作用在给定等待时长内锁没有被另外的线程持有,并且当前线程也没有被中断,则获得该锁,通过该方法可以实现锁对象的限时等待。package ...

    Java多线程:tryLock()方法

    tryLock(long time, TimeUnit unit) 的作用在给定等待时长内锁没有被另外的线程持有,并且当前线程也没有被中断,则获得该锁,通过该方法可以实现锁对象的限时等待。

    package com.wkcto.lock.reentrant;

    import java.util.concurrent.TimeUnit;

    import java.util.concurrent.locks.ReentrantLock;

    /**

    *tryLock(long time, TimeUnit unit) 的基本使用

    */

    public class Test07 {

    static class TimeLock implements Runnable{

    private static ReentrantLock lock = new ReentrantLock(); //定义锁对象

    @Override

    public void run() {

    try {

    if ( lock.tryLock(3, TimeUnit.SECONDS) ){ //获得锁返回true

    System.out.println(Thread.currentThread().getName() + "获得锁,执行耗时任务");

    // Thread.sleep(4000); //假设Thread-0线程先持有锁,完成任务需要4秒钟,Thread-1线程尝试获得锁,Thread-1线程在3秒内还没有获得锁的话,Thread-1线程会放弃

    Thread.sleep(2000); //假设Thread-0线程先持有锁,完成任务需要2秒钟,Thread-1线程尝试获得锁,Thread-1线程会一直尝试,在它约定尝试的3秒内可以获得锁对象

    }else { //没有获得锁

    System.out.println(Thread.currentThread().getName() + "没有获得锁");

    }

    } catch (InterruptedException e) {

    e.printStackTrace();

    } finally {

    if (lock.isHeldByCurrentThread()){

    lock.unlock();

    }

    }

    }

    }

    public static void main(String[] args) {

    TimeLock timeLock = new TimeLock();

    Thread t1 = new Thread(timeLock);

    Thread t2 = new Thread(timeLock);

    t1.start();

    t2.start();

    }

    }

    tryLock()仅在调用时锁定未被其他线程持有的锁,如果调用方法时,锁对象对其他线程持有,则放弃,调用方法尝试获得没,如果该锁没有被其他线程占用则返回true表示锁定成功; 如果锁被其他线程占用则返回false,不等待。

    package com.wkcto.lock.reentrant;

    import java.util.concurrent.locks.ReentrantLock;

    /**

    *tryLock()

    * 当锁对象没有被其他线程持有的情况下才会获得该锁定

    */

    public class Test08 {

    static class Service{

    private ReentrantLock lock = new ReentrantLock();

    public void serviceMethod(){

    try {

    if (lock.tryLock()){

    System.out.println(Thread.currentThread().getName() + "获得锁定");

    Thread.sleep(3000); //模拟执行任务的时长

    }else {

    System.out.println(Thread.currentThread().getName() + "没有获得锁定");

    }

    } catch (InterruptedException e) {

    e.printStackTrace();

    } finally {

    if (lock.isHeldByCurrentThread()){

    lock.unlock();

    }

    }

    }

    }

    public static void main(String[] args) throws InterruptedException {

    Service service = new Service();

    Runnable r = new Runnable() {

    @Override

    public void run() {

    service.serviceMethod();

    }

    };

    Thread t1 = new Thread(r);

    t1.start();

    Thread.sleep(50); //睡眠50毫秒,确保t1线程锁定

    Thread t2 = new Thread(r);

    t2.start();

    }

    }

    package com.wkcto.lock.reentrant;

    import java.util.Random;

    import java.util.concurrent.locks.ReentrantLock;

    /**

    * 使用tryLock()可以避免死锁

    */

    public class Test09 {

    static class IntLock implements Runnable{

    private static ReentrantLock lock1 = new ReentrantLock();

    private static ReentrantLock lock2 = new ReentrantLock();

    private int lockNum; //用于控制锁的顺序

    public IntLock(int lockNum) {

    this.lockNum = lockNum;

    }

    @Override

    public void run() {

    if ( lockNum % 2 == 0 ){ //偶数先锁1,再锁2

    while (true){

    try {

    if (lock1.tryLock()){

    System.out.println(Thread.currentThread().getName() + "获得锁1, 还想获得锁2");

    Thread.sleep(new Random().nextInt(100));

    try {

    if (lock2.tryLock()){

    System.out.println(Thread.currentThread().getName() + "同时获得锁1与锁2 ----完成任务了");

    return; //结束run()方法执行,即当前线程结束

    }

    } finally {

    if (lock2.isHeldByCurrentThread()){

    lock2.unlock();

    }

    }

    }

    } catch (InterruptedException e) {

    e.printStackTrace();

    } finally {

    if (lock1.isHeldByCurrentThread()){

    lock1.unlock();

    }

    }

    }

    }else { //奇数就先锁2,再锁1

    while (true){

    try {

    if (lock2.tryLock()){

    System.out.println(Thread.currentThread().getName() + "获得锁2, 还想获得锁1");

    Thread.sleep(new Random().nextInt(100));

    try {

    if (lock1.tryLock()){

    System.out.println(Thread.currentThread().getName() + "同时获得锁1与锁2 ----完成任务了");

    return; //结束run()方法执行,即当前线程结束

    }

    } finally {

    if (lock1.isHeldByCurrentThread()){

    lock1.unlock();

    }

    }

    }

    } catch (InterruptedException e) {

    e.printStackTrace();

    } finally {

    if (lock2.isHeldByCurrentThread()){

    lock2.unlock();

    }

    }

    }

    }

    }

    }

    public static void main(String[] args) {

    IntLock intLock1 = new IntLock(11);

    IntLock intLock2 = new IntLock(22);

    Thread t1 = new Thread(intLock1);

    Thread t2 = new Thread(intLock2);

    t1.start();

    t2.start();

    //运行后,使用tryLock()尝试获得锁,不会傻傻的等待,通过循环不停的再次尝试,如果等待的时间足够长,线程总是会获得想要的资源

    }

    }

    展开全文
  • tryLock()可能无法获取锁.因此,如果我们使用返回值执行工作,那么我们可能根本不做任何工作.Lock lock = new ReentrantLock();boolean isLocked = lock.tryLock();if (isLocked) {try {doWork();} finally {lock....
  • } } /** * 使用tryLock进行尝试锁定,不管锁定与否,方法都将继续执行 * 可以根据tryLock的返回值来判定是否锁定 * 也可以指定tryLock的时间,由于tryLock(time)抛出异常,所以要注意unclock的处理,必须放到...
  • tryLock的使用

    2021-05-02 09:44:48
    tryLock的使用业务场景方法说明用法 业务场景 对于某些并发业务场景,我们可能想保证同一时刻只有一个线程在执行某一方法。 例如:对于缓存的初始化工作,此时我们可以使用tryLock()方法对代码进行上锁,只有拿到锁...
  • linux 多线程锁的问题 trylock得不到锁如题:测试代码如下,为何线程一中while的最后不sleep1s,那么线程2trylock就永远的得不到锁,这个正常吗?#include#includepthread_mutex_tmutex;pthread_cond_tcond;intsum=0...
  • synchronized重量级锁,JDK前期的版本lock比synchronized更快,在JDK1.5之后synchronized引入了偏向锁,轻量级锁和重量级锁。以致两种锁性能旗鼓相当,看个人喜欢,本文主要介绍一下怎么简单使用lock。2....
  • 因此实际业务中,需要按照tryLock的返回值,进行判断后执行后面的业务代码 package test; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks...
  • 我有两个进程可以查看相同的文件,并希望实现文件锁定.问题似乎是一个进程用java编写而另一个进程用C编写,并且不清楚java端如何实现低级锁定.该平台是Solaris 10....但是,java tryLock()会在第二次尝试时...
  • 方式一 RLock lock = redissonClient.getLock(... if (lock.tryLock(5, 10, TimeUnit.SECONDS)) { //业务处理 } else { Assert.isTrue(false, "排队中,请稍后重试!"); } } catch (InterruptedException e) { .
  • go两种方式实现trylock

    2021-06-07 20:18:55
    看了下标准库没有实现trylock 构思了下有两种方式实现 1 是利用原子性 思路是某个值能否改变 2 是利用channel 和select 思路是有缓存管道 能往里面写证明可以加锁 业务处理完了 再取出值 可以做到信号量的作用同时...
  • lock package com.yf.reentrantLock; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class DemoLock { public static void main(String[] args) { int ...
  • golang 如何给Mutex添加一个TryLock 以下是Mutex的结构体: type Mutex struct { state int32 sema uint32 } 其中state字段用来表示这个Mutex的状态,即是否被锁: 0 表示未锁,二进制表示为 0000 1 表示已锁住,...
  • ReentrantLock: Lock():阻塞加锁,无...tryLock():尝试枷锁,布尔类型返回值,线程有锁返回true,反之返回false,不会阻塞 利用tryLock()可以有自旋锁, 自旋锁对cpu消耗较大,但是性能要优于lock()方法 ...
  • Lock和TryLock的区别 1: lock拿不到锁会一直等待。tryLock是去尝试,拿不到就返回false,拿到返回true。 2: tryLock是可以被打断的,被中断 的,lock是不可以。 举一个例子如下: 假如线程A和线程B使用同一个锁LOCK...
  • Reentrantlock可以进行“尝试锁定”tryLock package cn.qqjx.thread; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /* ...
  • 函数down_write_trylock()是写者用来尝试得到读写信号量sem时调用的,它与down_write()的功能类似,只是它不会导致调用者睡眠,即调用该函数的进程在不能获取信号量的情况下会立即返回,不会睡眠。down_write_try...
  • =(pthread_mutex_trylock((pthread_mutex_t *)obj_))) { perror("pthread_mutex_trylock"); printf("pthread_mutex_trylock errorn"); return -1; } else return 0; } int main() { taxiMutex=knCreateMutex()...
  • Lock的tryLock()方法

    2021-03-10 01:46:18
    概述tryLock 是防止自锁的一个重要方式。tryLock()方法是有返回值的,它表示用来尝试获取锁,如果获取成功,则返回true,如果获取失败(即锁已被其他线程获取),则返回false,这个方法无论如何都会立即返回。在拿不到...
  • 在前文ReentrantLock-NonfairSync源码逐行深度分析中,已经分析了AQS加解锁,阻塞唤醒与CLH队列的使用,这里主要看看带超时时间的tryLock实现。 在ReentrantLock的tryLock(timeout)方法中调用的是sync的...
  • 如果您需要支持tryLock操作的Lock,则不能使用Java的固有锁定功能.您必须实现自己的Lock类,该类维护所需的状态,即所有者Thread和计数器,并且可能使用固有锁定来实现其线程安全的更新和阻止(在较旧的Java版本中没有很...
  • ReentrantLock ReentrantLock(轻量级锁)也可以叫...以致两种锁性能旗鼓相当,看个人喜欢,本文主要介绍一下lock和tryLock的区别。 public void lock() { sync.lock(); } public void lockInterruptibly() thro

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 290,257
精华内容 116,102
关键字:

trylock