簡體   English   中英

Java中基於名稱的可重入鎖

[英]Name based Reentrant Lock in Java

我的問題是我想要一個可以在一個線程中創建並在另一個線程中釋放的基於用戶的鎖。 我試圖使用Reetant鎖,但是我的想法在某個地方不盡人意。

即有藍色,綠色和紫色的人。 每個顏色組只有一把鏟子。 如果紫色組需要使用鐵鍬,則需要等待鐵鍬可用。 在給定的時刻,藍色組和紫色組都可以使用各自的鏟子。

主類

public class MainReentrant {

    public static ConcurrentHashMap<String, ReentrantLock> locks;

    public static void main(String[] args){

            locks = new ConcurrentHashMap<String, ReentrantLock>();

            new Thread( new ReentrantEx(1)).start();;
            new Thread( new ReentrantEx(1)).start();;
            new Thread( new ReentrantEx(2)).start();;

    }
}

第一步是創建一個鎖並將其鎖定。

public class ReentrantEx implements Runnable {
    private Integer id;

    public ReentrantEx(Integer id){
        this.id = id;
    }
    public void doSomethingPerUser(Integer i){
        synchronized(i){
            ReentrantLock tempLock = MainReentrant.locks.get(i.toString());

            if(tempLock != null){
                //we have an unlocked lock
                tempLock.lock();
            }else{
                //add a new lock for this customer
                tempLock = new ReentrantLock();
                tempLock.lock();
                MainReentrant.locks.put(i.toString(), tempLock);
            }

            System.out.println("doSomethingPerUser lock should be held : " + i);

            new Thread(new RandomRunnable(i)).start();

        }
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        doSomethingPerUser(id);

    }
}

接下來,randomRunnable類嘗試釋放由ReentrantEx創建的鎖

public class RandomRunnable implements Runnable {

    private Integer id; 
    public RandomRunnable(Integer id){
        this.id = id;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub

        System.out.println(" RandomRunnable: id = "+ id );

        ReentrantLock tempLock = MainReentrant.locks.get(id.toString());

        synchronized(tempLock){
            if(tempLock == null){
                System.out.println("ERROR: we have a lock that we cannot free");
                return;
            }else{
                tempLock.unlock();
                //ReentrantEx.locks.put(id.toString(), tempLock);
            }
        }
    }

}  

每當我這樣做時,都會出現以下錯誤:

Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:127)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1239)
    at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:431)
    at test.RandomRunnable.run(RandomRunnable.java:25)
    at java.lang.Thread.run(Thread.java:695)       

這里是對一般的鎖一個很好的鏈接...

簡而言之, ReentrantLock不適合您。 獲得該鎖的主題是一個線程 ,因此當您嘗試在另一個線程中釋放它時,該線程實際上正在嘗試釋放它不擁有的鎖。 同時,獲得它的線程繼續堅持下去。

相反,您可能需要的是一個Semaphore -更具體地說,是一組信號燈,每個顏色組一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM