日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

信号量使用例子_用信号量锁定:一个例子

發布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 信号量使用例子_用信号量锁定:一个例子 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

信號量使用例子

并發是帶來有趣挑戰的一個方面。 如果處理不當,會帶來種族問題,這會使人們感到困惑,因為這些問題有時會突然出現,并且有時會正常工作。

當處理訪問公共資源的并發線程時,Java語言提供了許多處理競爭條件的方法。 一些包括;

  • 使用volatile關鍵字
  • 使用java.util.concurrent和 java.util.concurrent.atomic中可用的類
  • 同步塊
  • 使用信號量
  • 當然,可能還有更多我可能不知道的事情。 今天,我想向大家展示的例子是使用
    信號量 。 它是從JDK 1.5引入的,使開發人員能夠無縫獲取和釋放鎖。 同樣,我將展示的示例是一個假設的場景,該場景僅用于描述使用信號量可以實現的效果,因此請不要關注代碼的固有細節:)。

    因此,在這種情況下,存在一個內存緩存中保存了類型為
    '人'。 用戶可以使用緩存插入和檢索記錄。 這里的問題是我們將使用信號量來控制對內存緩存的并發訪問。 現在,我不想給您帶來更多文本,讓我們開始業務并顯示一些代碼;

    import java.util.concurrent.Semaphore;/*** This class will allow thread to acquire and release locks as required* * @author dinuka.arseculeratne* */ public class PersonLock {/*** We do not want multiple lock objects lying around so we make ths class* singleton*/private PersonLock() {}/*** Bill Pugh's way of lazy initializing the singleton instance* * @author dinuka.arseculeratne* */private static class SingletonHolder {public static final PersonLock INSTANCE = new PersonLock();}/*** Use this method to get a reference to the singleton instance of* {@link PersonLock}* * @return the singleton instance*/public static PersonLock getInstance() {return SingletonHolder.INSTANCE;}/*** In this sample, we allow only one thread at at time to update the cache* in order to maintain consistency*/private Semaphore writeLock = new Semaphore(1);/*** We allow 10 concurrent threads to access the cache at any given time*/private Semaphore readLock = new Semaphore(10);public void getWriteLock() throws InterruptedException {writeLock.acquire();}public void releaseWriteLock() {writeLock.release();}public void getReadLock() throws InterruptedException {readLock.acquire();}public void releaseReadLock() {readLock.release();} }

    此類將處理獲取和釋放使我們的緩存線程安全所需的鎖的過程。 我在這里使用了兩個單獨的鎖來進行讀寫。 其背后的原理是允許用戶讀取數據,盡管在讀取時可能已過時。

    請注意,我已經使用
    這里的“十”表示十個線程可以同時獲取鎖并出于讀取目的訪問緩存。 接下來,您可以在寫入鎖定中看到,我已經使用了“
    一個”表示一次只能有一個線程可以訪問緩存以將項目放入緩存。 這對于維護緩存內的一致性很重要。 也就是說,我不希望有多個線程試圖將項目插入到地圖中,這將導致不可預測的行為(至少在某些情況下)。 使用信號量獲取鎖主要有兩種方法。

    1. Acquisition() :是一個阻塞調用,它等待直到釋放鎖或線程被中斷為止

    2. tryAcquire() :是一個非阻塞調用,它將立即返回并返回true或false,表示是否已獲得鎖定。

    在這里,我使用了阻塞獲取調用,因為我希望線程等待直到鎖可用。 當然,這取決于您的用例。 您還可以在tryAcquire()方法中定義超時期限,以使線程不會無限期地等待鎖定。

    接下來,下面的存儲類顯示了我如何使用鎖類在緩存中插入和讀取數據。

    import java.util.HashMap; import java.util.Map;/*** A mock storage to hold the person objects in a map* * @author dinuka.arseculeratne* */ public class PersonStorage {private Map<Integer, Person> personCache = new HashMap<Integer, Person>();private int counter = 0;/*** This class is made singleton and hence the constructor is made private*/private PersonStorage() {}/*** Bill Pugh's way of lazy initializing the singleton instance* * @author dinuka.arseculeratne* */private static final class SingletonHolder {public static final PersonStorage INSTANCE = new PersonStorage();}/*** Use this method to get a reference to the singleton instance of* {@link PersonStorage}* * @return the singleton instance*/public static PersonStorage getInstance(){return SingletonHolder.INSTANCE;}/*** Inserts the person into the map. Note that we use defensive copying so* that even if the client changes the object later on, those changes will* not be reflected in the object within the map* * @param person* the instance of {@link Person} to be inserted* @return the key which signifies the location of the person object* @throws InterruptedException*/public int putPerson(Person person) throws InterruptedException {Person copyPerson = person.copyPerson();personCache.put(++counter, copyPerson);return counter;}/*** Here as well we use defensive copying so that the value of the object* reference within the map is not passed in to the calling party.* * @param id* the id representing the location of the object within the map* @return the instance of the {@link Person} represented by the key passed* in* @throws InterruptedException*/public Person retrievePerson(int id) throws InterruptedException {PersonLock.getInstance().getReadLock();if (!personCache.containsKey(id)) {throw new RuntimeException('Key is not found');}PersonLock.getInstance().releaseReadLock();return personCache.get(id).copyPerson();}}

    顯然,代碼也可以在沒有鎖的情況下工作,但是問題是應用程序將不一致,并且每次運行都會提供不同的結果。 這不是您希望應用程序執行的操作,因此使用鎖可以確保應用程序始終運行。

    最后是一個小型測試類,以展示其工作方式; 并不是在這里我們在調用putPerson()方法之前獲得了鎖,并在finally塊中釋放了該鎖,以確保釋放該鎖。

    /*** A test class to demonstrate the locking at work* * @author dinuka.arseculeratne* */ public class TestLock {public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {Person p1 = new Person(1L, 'Test1', 'XYZ');try { PersonLock.getInstance().getWriteLock(); PersonStorage.getInstance().putPerson(p1);} catch (InterruptedException e) {// Exception handling need to be donee.printStackTrace();}finally{PersonLock.getInstance().releaseWriteLock();}}});Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {Person p2 = new Person(2L, 'Test123', 'ABC');try { PersonLock.getInstance().getWriteLock();PersonStorage.getInstance().putPerson(p2);} catch (InterruptedException e) {// Exception handling need to be done}finally{PersonLock.getInstance().releaseWriteLock();}}});t1.start();t2.start();System.out.println(PersonStorage.getInstance().retrievePerson(2));} }

    以上是我對使用Sempahores來確保代碼線程安全的簡短介紹的總結,對于任何想使用該代碼的人來說,都可以從
    在這里 。 嘗試刪除Storage類中的鎖,并查看其在每次運行中的行為。 您將看到可能發生的比賽情況。

    參考: 使用信號燈鎖定:我們的JCG合作伙伴 Dinuka Arseculeratne 的示例,來自“ IT之旅”博客。


    翻譯自: https://www.javacodegeeks.com/2012/10/locking-with-semaphore-example.html

    信號量使用例子

    總結

    以上是生活随笔為你收集整理的信号量使用例子_用信号量锁定:一个例子的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。