我的问题是我想要一个基于用户的锁,我可以在一个线程中创建并在另一个线程中发布。我试图使用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
答案 0 :(得分:4)
简单地说,ReentrantLock
不适合你。获取锁的主题是线程,因此当您尝试在另一个线程中释放它时,该线程实际上是在尝试释放它不拥有的锁。与此同时,获得它的线程仍然坚持下去。
您可能需要的是Semaphore
- 更具体地说,是一组信号量,每个颜色组一个。