I have a scheduled method call which on the scheduled time calls the following method:
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
}
}
The method signature of workNow
is like:
workNow() throws CustomException
workNow
method runs for several minutes and does some work. My issue is, when one workNow
for FRUIT
(or VEGETABLE
) is going on and another invoke happens with same type (FRUIT
for example), it creates a new FruitClass
instance and starts executing its workNow
parallelly.
How do I control this behavior? I want the second invocation through second object to wait until first workNow
through first object is not complete.
To clarify:
Parallel invocation of
FRUIT
andVEGETABLE
is fine. I want to control parallel invocation of same type. Two or moreFRUIT
or two or moreVEGETABLE
.I can not make
FruitClass
andVegetableClass
as singletons. I need some wrapping code aroundnew
to work how I want.
Do the synchronisation on a class object, and this will be enough to avoid creation of another class until finished:
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
}
}
synchronized
on class object uses the class instance as a monitor. Class object is actually a singleton (the object representing the class metadata at runtime), and only one thread can be in this block.