我有一个预定的方法调用,它在预定的时间调用以下方法:
private void doSomething(Map<String, String> someArguments) throws CustomException {
MyEnum runType = getRunType(someArguments);
switch (runType) {
case FRUIT:
new FruitClass().workNow();
break;
case VEGETABLE:
new VegetableClass().workNow();
break;
default:
// log that the type is not known
}
}
的方法签名workNow
是这样的:
workNow() throws CustomException
workNow
方法运行几分钟并做一些工作。我的问题是,当一个workNow
for FRUIT
(or VEGETABLE
) 正在进行并且另一个调用发生在相同类型(FRUIT
例如)时,它创建了一个新FruitClass
实例并开始workNow
并行执行它。
我将其解决为:
private void doSomething(Map<String, String> someArguments) {
MyEnum runType = getRunType(someArguments);
switch (runType) {
case FRUIT:
synchronized (FruitClass.class){
new FruitClass().workNow();
}
break;
case VEGETABLE:
synchronized (VegetableClass.class){
new VegetableClass().workNow();
}
break;
default:
// log that the type is not known
}
}
从这个问题的答案。
这工作正常。但是它在同步类上构建了一个等待线程的队列,只要前一个线程释放它就获取锁。
只是为了增强我的知识,有没有办法确定当一个线程进入并看到类上的锁时,而不是进入等待,它只是被终止。
换句话说,“我来这里是为了做workNow
。让我锁定FruitClass
。哦!其他线程已经拥有锁定并且正在做workNow
。我不需要做任何事情。终止。”
如何在这里实现这一目标?
编辑1:
从下面的答案:
final Lock reentrantLock = new ReentrantLock();
private void doSomething(Map<String, String> someArguments) {
MyEnum runType = getRunType(someArguments);
switch (runType) {
case FRUIT:
if(reentrantLock.tryLock()) {
try {
new FruitClass().workNow();
} finally {
reentrantLock.unlock();
}
} else {
// do nothing and terminate
}
break;
case VEGETABLE:
synchronized (VegetableClass.class){
new VegetableClass().workNow();
}
break;
default:
// log that the type is not known
}
}
但是,这显然不会起作用。因为这只会实例化 new FruitClass
,调用 process 并释放锁。
正如我最初的问题所说,我想锁定新对象本身的创建,如果一个对象已经创建并且正在执行workNow
.
我如何使用锁实现这一点?
我不知道这样的事情是否可能:
final Lock reentrantLock = new ReentrantLock(FruitClass.class);
如果我的问题是正确的,那么您将使用更多“细粒度”的方法来处理 Java 同步。使用“同步”不仅足够灵活。
解决这个问题的一种方法是使用java.util.concurrent.locks
包提供的锁。
Locks 特别是提供tryLock
方法,它只是尝试获取锁,但如果它已经被另一个线程拥有它就不会进入临界区,您可以尝试一段时间或立即继续,API 是灵活的足以允许它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句