基于名称的Java中的重入锁定

时间:2014-09-25 20:14:52

标签: java multithreading locks

我的问题是我想要一个基于用户的锁,我可以在一个线程中创建并在另一个线程中发布。我试图使用reetrant锁,但我的想法在某处不足。

即。有蓝色,绿色和紫色的人。每个颜色组只有一个铲子。如果紫色组需要使用铲子,他们需要等待铲子可用。蓝色组和紫色组都可以在给定时刻具有各自的铲子。

Mainclass

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);

    }
}

next 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)       

这里有一个关于锁的好链接... locks

1 个答案:

答案 0 :(得分:4)

简单地说,ReentrantLock不适合你。获取锁的主题是线程,因此当您尝试在另一个线程中释放它时,该线程实际上是在尝试释放它不拥有的锁。与此同时,获得它的线程仍然坚持下去。

您可能需要的是Semaphore - 更具体地说,是一组信号量,每个颜色组一个。