我不明白这段代码有什么问题。有时两个线程开始执行 try block 。每次调用该函数时,我都会创建一个新的 popo
实例。请问有人能弄清楚问题出在哪里吗?
public class Instance {
private static AtomicInteger i = new AtomicInteger(0);
public synchronized void incrementInstance() {
i.getAndIncrement();
}
public synchronized void decrementInstance() {
i.getAndDecrement();
}
public synchronized int getInstances() {
return i.get();
}
}
public class popo {
private static volatile MyMutex instanceMutex = new MyMutex();
public void doSomething() {
synchronized (instanceMutex) {
final Instance no = new Instance();
if (no.getInstances() > 0) {
instanceMutex.wait();
} else {
no.incrementInstance();
}
}
try {
// do something
} finally {
synchronized (instanceMutex) {
final Instance no = new Instance();
if (no.Instances() > 0) {
no.decrementInstance();
}
instanceMutex.notify();
}
}
}
private static class MyMutex {}
}
最佳答案
我认为代码到处都是味道:-)实际上,创建新实例之类的事情只不过是访问静态字段,这会让事情变得困惑(请参阅之前的回复)。所以,这就是我的建议:
- 如果您正在编写新代码,则应避免使用等待/通知。查看并发包和《Effective Java》一书中的 Item69。
- 根据我对您代码的理解,您需要一个如下信号量:
static final Semaphore SEMAPHORE = new Semaphore(1);
...
SEMAPHORE.take(); // blocks, only one thread is allowed to proceed
try{
//critical section
} finally {
SEMAPHORE.release(); // never blocks, always within a finally block
}
然后您可以使用 getQueueLength() 方法来了解有多少线程正在等待并替换您正在使用的 AtomicInteger。请参阅http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Semaphore.html
- 考虑使用执行人。然后,一旦提交了任务,就可以等待Future了。
- 如果您仍然想使用 wait/notify,请确保将所有代码放在同步块(synchronized block)中并使用标准习惯用法(Effective Java 中的 Item69):
synchronized(instanceMutex) {
while(< condition does not hold >) {
obj.wait();
}
// Perform required actions
}
关于java - 另一个线程进入互斥体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8360301/