DependingService
依赖于service
异步和动态注入到DependingService.setService(Object)
的对象。如果在service
对象被设置之前调用DependingService.doSomething()
,则线程应该等待5秒钟以使service
可用。ReadWriteLock等待对象被设置
如何做适当和有效的锁定?我的第一种方法是这样的:
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class DependingService {
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Condition condition = rwLock.writeLock().newCondition();
private Object service;
// service injected dynamically by container
public void setService(final Object service) {
rwLock.writeLock().lock();
try {
this.service = service;
System.out.println("Signalling");
condition.signalAll();
} finally {
rwLock.writeLock().unlock();
}
}
public void doSomething() {
rwLock.readLock().lock();
try {
if (service == null) {
// we can't upgrade to write lock, so release read lock first
rwLock.readLock().unlock();
rwLock.writeLock().lock();
try {
if (service == null) {
System.out.println("Waiting fo 5 seconds");
condition.await(5, TimeUnit.SECONDS);
}
} catch (final InterruptedException e) {
e.printStackTrace();
} finally {
// downgrade to read lock
rwLock.readLock().lock();
rwLock.writeLock().unlock();
}
if (service == null) {
throw new RuntimeException("service is null");
}
}
// use the service
System.out.println(service.toString());
} finally {
rwLock.readLock().unlock();
}
}
}
编辑: 注意DependingService.setService(Object)
可以被设置为NULL随时随地多次或任何其他对象。
'setServive'多久调用一次?每秒多次(100+)?每x秒/分钟一次? – assylias
你的代码的一个问题是'condition.await(...)'可能会虚假地唤醒 - 所以你应该把这个语句放在一个循环中,在这种情况下你的超时将不再起作用。 – assylias
assylias:通常应该只调用一次,但没有人不知道(它实际上是在OSGi环境中) –