亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

lock.tryLock()方法的使用

lock.tryLock()方法的使用

九州編程 2019-03-12 13:10:51
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<Object> list = new ArrayList<Object>();    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<Object> list = new ArrayList<Object>();    private Lock         lock = new ReentrantLock();運行結果如下:第二個線程  得到了鎖.第一個線程  獲取鎖失敗.第二個線程  釋放了鎖.問題如下:我知道lock()方法去獲取鎖,當獲取不到鎖的時候,會一直等待。直到獲取到鎖。tryLock()方法獲取鎖的時候,制作一次試探,如果獲取鎖失敗,就不會一直等待的。如果是這樣的話,如我Demo所示的這樣,在業務邏輯中使用tryLock很容易造成程序不可控。比較疑惑這個tryLock的使用方法。。求大神解釋。。謝謝~~
查看完整描述

4 回答

?
夢里花落0921

TA貢獻1772條經驗 獲得超6個贊

這個最好把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,去執行下面的邏輯。


是否會造成 程序不可控, 不在于這幾種方式本身,在于業務類別和使用邏輯上。


查看完整回答
反對 回復 2019-04-19
?
慕后森

TA貢獻1802條經驗 獲得超5個贊

為什么說會造成程序不可控呢,調用tryLock方法之后會立即返回結果,根據是否獲得鎖然后做出相應的業務操作,相比較于lock方法會一直阻塞這本身已經使程序更可控了。


查看完整回答
反對 回復 2019-04-19
?
慕的地8271018

TA貢獻1796條經驗 獲得超4個贊

不同的方法有不同的用處啊,只是應用的場景不同,不是不可控


查看完整回答
反對 回復 2019-04-19
?
侃侃爾雅

TA貢獻1801條經驗 獲得超16個贊

題主這里對程序可控的理解是指每一個任務都按照要求執行,但我覺得既然用tryLock()這個非阻塞的場景,就是要允許某些任務不執行(比如防止重復提交業務),或超時不執行(比如防止資源等待隊列溢出)等。


查看完整回答
反對 回復 2019-04-19
  • 4 回答
  • 0 關注
  • 3434 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號