欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java并發(fā)之Lock接口的深入講解

 更新時間:2021年08月04日 10:36:07   作者:毅航同學  
從Java 5之后,在java.util.concurrent.locks包下提供了另外一種方式來實現(xiàn)同步訪問.那就是Lock,這篇文章主要給大家介紹了關于java并發(fā)之Lock接口的相關資料,需要的朋友可以參考下

Juc中各種各樣鎖信息

在java的juc包為我們提供了各種各樣的鎖信息。如果細心來看其大部分都會實現(xiàn)一個名為LOCK的接口信息本文皆在幫你回顧Lock信息;

通過本文你將了解到如下內容:

1.Lock和synchronized的對比

2.Lock中常見API的總結

synchronized面臨缺點

鎖的出現(xiàn)主要是為了保證在并發(fā)訪問共享資源時不出現(xiàn)錯。 在java中如果不考慮性能損耗問題,那么對共享的資源信息加上synchrionzed關鍵字基本就可以解決大多數(shù)并發(fā)帶來的問題,但是也隨之帶來靈活性和效率上的問題:

 效率方面:

1.     此種情況下鎖的釋放情況較少,很容易到導致一直獨占資源而導致性能的下降。

2.     當我們試圖獲取鎖時不能直接指定具體條件

3.    不能中斷正在試圖獲得鎖的線程

靈活性:

 1.  當獲得鎖資源后,無法得知是否獲得鎖信息

 2.  僅當程序異常或順利執(zhí)行完時才會釋放鎖信息,缺乏主動釋放鎖的時機。

不適用的場景

場景1 :

當我們使用synchronized時,假如某線程獲取到鎖之后由于要等待IO或者其他原因進入阻塞狀態(tài),同時未釋放鎖信息,那么此時其他線程就只能一直等待。所以此時就需要synchronized有一種機制:避免等待的線程一直無期限地等待下去。
場景2 :

在讀文件信息形式,不同線程的寫操作是相互沖突的。但是讀操作并不會導致沖突。如果我們不加考慮的為資源信息加上synchronized關鍵字,那么當多線程同時操作時,只有一個線程可以獲取到資源,其他未獲得鎖信息的線程只能進入等待狀態(tài),從而導致讀寫效率不高。

Lock接口

Lock接口是對關鍵字synchronized的補充和擴展,它允許我們可以在線程安全的情況下更加靈活的操作共享資源信息。

常見用法:

Lock最佳實踐:

1.lock(),unlock()

一般來說,使用Lock必須在try…catch…塊中進行,并且將釋放鎖的操作放在finally塊中進行。這是因為lock并不會像synchronized那樣在異常時釋放鎖,所以必須保證有手動釋放的過程,這樣才能保證其它線程有獲取鎖的機會。

//  加鎖
lock.lock();
try{
    //處理任務
}catch(Exception ex){
​
}finally{
    //釋放鎖  (鎖的釋放一般放入到finally塊中進行,這樣保證了總會對鎖信息進行釋放)
    lock.unlock();   
}

2. tryLock() & tryLock(long time, TimeUnit unit)

tryLock()方法是有返回值的,它表示用來嘗試獲取鎖,如果獲取成功,則返回true;如果獲取失?。存i已被其他線程獲?。?,則返回false,也就是說,這個方法無論如何都會立即返回即使其無法獲取到鎖也不會一致等待。

tryLock(long time, TimeUnit unit)方法和tryLock()方法是類似的,只不過區(qū)別在于這個方法在拿不到鎖時會等待一定的時間,在時間期限之內如果還拿不到鎖,就返回false

如果一開始拿到鎖或者在等待期間內拿到了鎖,則返回true。一般情況下,通過tryLock來獲取鎖時是這樣使用的:

Lock lock = ...;
if(lock.tryLock()) {
     try{
         //處理任務
     }catch(Exception ex){
​
     }finally{
         lock.unlock();   //釋放鎖
     } 
}else {
    //如果不能獲取鎖,則直接做其他事情
}

3. lockInterruptibly()  

lockInterruptibly()方法比較特殊,當通過這個方法去獲取鎖時,如果線程 正在等待獲取鎖,則這個線程能夠 響應中斷,即中斷線程的等待狀態(tài)。

例如,當兩個線程同時通過lock.lockInterruptibly()想獲取某個鎖時,假若此時線程A獲取到了鎖,而線程B只有在等待,那么對線程B調用threadB.interrupt()方法能夠中斷線程B的等待過程。

public void method() throws InterruptedException {
    lock.lockInterruptibly();
    try {  
     //.....
    }
    finally {
        lock.unlock();
    }  
}

當一個線程獲取了鎖之后,是不會被interrupt()方法中斷的。因為interrupt()方法只能中斷阻塞過程中的線程而不能中斷正在運行過程中的線程。而在 synchronized 中,當一個線程處于等待某個鎖的狀態(tài),是無法被中斷的,只有一直等待下去,這也就是我們需要手動釋放鎖的原因。

給出如下的例子來進行驗證:創(chuàng)建兩個線程來共同爭搶lock鎖信息

public class LockInterruptibly implements Runnable {
​
    private Lock lock = new ReentrantLock();
public static void main(String[] args) {
    LockInterruptibly lockInterruptibly = new LockInterruptibly();
    Thread thread0 = new Thread(lockInterruptibly);
    Thread thread1 = new Thread(lockInterruptibly);
    thread0.start();
​
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    thread1.start();
    thread1.interrupt();
}
   // 任務執(zhí)行邏輯
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "嘗試獲取鎖");
        try {
            lock.lockInterruptibly();
            try {
                System.out.println(Thread.currentThread().getName() + "獲取到了鎖");
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + "睡眠期間被中斷了");
            } finally {
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + "釋放了鎖");
            }
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + "獲得鎖期間被中斷了");
        }
    }
}
​

執(zhí)行結果:

Thread-0嘗試獲取鎖
Thread-0獲取到了鎖
Thread-1嘗試獲取鎖
Thread-1獲得鎖期間被中斷了
Thread-0釋放了鎖

通過結果信息我們可以看出,lockInterruptibly()僅能中斷正在等待的線程信息,而無法中斷正在運行的線程。

對比 Lock和tryLock的區(qū)別

lock和tryLock都可以獲取到鎖信息,但兩者之間還是存在些差異的。 具體如下:

1: lock拿不到鎖會一直等待。tryLock是去嘗試,拿不到就返回false,拿到返回true。

2: tryLock是可以被打斷的,被中斷的,lock是不可以。

// 實例代碼 
public class LockDemo  implements Runnable{
  static Lock lock1 = new ReentrantLock();
    @Override
    public void run() {
        // 分別演示 lock,trylock區(qū)別
        // lock1.lock();
        lock1.tryLock();
        System.out.println("線程 " + Thread.currentThread().getName() + " 獲取到鎖信息 ");
    }
    
    
    public static void main(String[] args) throws InterruptedException {
        LockDemo r1 = new LockDemo();
        LockDemo r2 = new LockDemo();
        r1.flag = true;
        r2.flag = false;
        Thread t1 = new Thread(r1);
        Thread t2 = new Thread(r2);
​
        t1.start();
        Thread.sleep(1000);
        // 中斷
        t2.start();
        t2.interrupt();
    }
}
​

結果信息:

當執(zhí)行l(wèi)ock1.lock()時的輸出:可以看到lock方法并不能響應中斷信息,如果不解鎖則會一致持有鎖信息!

對于tryLock而言其可以響應中斷

總結

本篇對Lock接口中常用到的Api進行了分析和總結,同時分析了Lock接口和synchronized關鍵之間的關系,希望對你能有所啟發(fā).

到此這篇關于java并發(fā)之Lock接口的文章就介紹到這了,更多相關java并發(fā)Lock接口內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Netty分布式ByteBuf使用的底層實現(xiàn)方式源碼解析

    Netty分布式ByteBuf使用的底層實現(xiàn)方式源碼解析

    這篇文章主要為大家介紹了Netty分布式ByteBuf使用底層實現(xiàn)方式源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-03-03
  • java字符串轉數(shù)字及各種數(shù)字轉字符串的3種方法

    java字符串轉數(shù)字及各種數(shù)字轉字符串的3種方法

    這篇文章主要介紹了java字符串轉數(shù)字及各種數(shù)字轉字符串的3種方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • Java 線程池框架

    Java 線程池框架

    本文主要介紹了Java 線程池框架的相關知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • 如何使用Spring Cloud Feign日志查看請求響應

    如何使用Spring Cloud Feign日志查看請求響應

    這篇文章主要介紹了如何使用Spring Cloud Feign日志查看請求響應,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • System.getProperty(“l(fā)ine.separator“)含義及意義詳解

    System.getProperty(“l(fā)ine.separator“)含義及意義詳解

    這篇文章主要介紹了System.getProperty(“l(fā)ine.separator“)含義,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • IDEA中try catch拋異??旖萱I分享

    IDEA中try catch拋異??旖萱I分享

    在編寫Java代碼時,使用IDEA的快捷鍵CTRL+ALT+t可以快速生成try..catch語句塊,有效提高編碼效率,首先選擇需要處理的代碼片段,然后按下快捷鍵,選擇try/catch選項,即可自動包圍選中代碼,這一快捷操作簡化了異常處理步驟,減少了手動編寫的時間,是編程中的實用技巧
    2024-10-10
  • 妙用Java8中的Function接口消滅if...else

    妙用Java8中的Function接口消滅if...else

    在開發(fā)過程中經(jīng)常會使用if...else...進行判斷拋出異常、分支處理等操作。這些if...else...充斥在代碼中嚴重影響了代碼代碼的美觀,本文就妙用Java8中的Function接口消滅if...else,感興趣的可以了解一下
    2022-01-01
  • spring data JPA 中的多屬性排序方式

    spring data JPA 中的多屬性排序方式

    這篇文章主要介紹了spring data JPA 中的多屬性排序方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • SpringBoot?mybatis-plus使用json字段實戰(zhàn)指南

    SpringBoot?mybatis-plus使用json字段實戰(zhàn)指南

    在現(xiàn)代應用開發(fā)中經(jīng)常會使用JSON格式存儲和傳輸數(shù)據(jù),為了便捷地處理數(shù)據(jù)庫中的JSON字段,MyBatis-Plus提供了強大的JSON處理器,這篇文章主要給大家介紹了關于SpringBoot?mybatis-plus使用json字段的相關資料,需要的朋友可以參考下
    2024-01-01
  • java截取字符串中的指定字符的兩種方法(以base64圖片為例)

    java截取字符串中的指定字符的兩種方法(以base64圖片為例)

    本文介紹了使用Java截取字符串中指定字符的方法,通過substring索引和正則實現(xiàn),文章詳細介紹了實現(xiàn)步驟和示例代碼,對于想要了解如何使用Java截取字符串指定字符的讀者具有一定的參考價值
    2023-08-08

最新評論