JUnit5 check exception is thrown in thread - java

I have some service like this:
class SomeService{
private final Executor executor = Executors.newFixedThreadPool(10);
void handle(SomeEvent event) {
executor.execute(
() -> {
//... logic omitted
if (isBadCase()) {
throw new RuntimeException("Something bad happen");
}
//... time consuming logic continued
}
);
}
...
//other methods
}
And I want to test "badCase", that RuntimeException("Something bad happen") is thrown.
Is it possible to achieve using JUnit5?
For other cases "normal" or "notSoBad" I've implemented workaround which is just a wait cycle for some condition is met for corresponding case, like this:
private void awaitForNormalConditionIsMet(int seconds) {
for (int step = 1; step <= seconds * 40; step++) {
if (normalConditionIsMet()) return;
else {
try {
System.out.println("Waiting for condition - " + (step * 25) + "ms");
Thread.sleep(25);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Assertions.fail();
}
And this workaround works well when I have something corresponding to check.
But for the "badCase" nothing corresponding is changed, only the exception is thrown.
And I cannot extract the exception throwing logic from executor.
Could you please help?

You might want to refactor code especially if your Runnable has more complex logic.
If you make it a separate unit to test you have more control with it. And testing is more easy, for example:
public class SomeService {
private final Executor executor = Executors.newFixedThreadPool(10);
void handle(SomeEvent event) {
executor.execute(new MyRunnable(event));
}
// This is inner non-static in my example class because isBadCase()
// could be in service. Of course this isBadCase could be anywhere.
public class MyRunnable implements Runnable {
private SomeEvent event;
public MyRunnable(SomeEvent event) {
this.event = event;
}
#Override
public void run() {
if (isBadCase()) {
throw new RuntimeException("Something bad happen");
}
}
}
public boolean isBadCase() {
return false;
}
}
Now there is no problem with threads or so because you can catch the exception in main thread directly and at the same time you are doing more granular unit testing of your code:
#ExtendWith(MockitoExtension.class)
class SomeServiceTest {
// Spy is because you want to mock normal case for isBadCase = false
// to true so causing the exception to be thrown
#Spy
private SomeService someService;
#Test
void testOk() {
someService.new MyRunnable(new SomeEvent()).run();
}
#Test
void testBadCase() {
Mockito.when(someService.isBadCase()).thenReturn(true);
MyRunnable myRunnable = someService.new MyRunnable(new SomeEvent());
assertThrows(RuntimeException.class, () -> myRunnable.run());
}
}

Related

Wait for method which return DeferredResult

I have service method which return DefferedResult<Foo> in few seconds, but I need my code will wait until that method finish and return deferred result with set result.
Here is sample code:
#Service
public class FooService {
// ...
public DeferredResult<Foo> fetchFoo(long id) throws InterruptedException {
DeferredResult<Foo> fooDeferredResult = new DeferredResult<>();
concurrentMap.put(id, fooDeferredResult);
return fooDeferredResult;
}
// this you can figure out as some handler or scheduler which receive messages and is called
public void anotherMethod(Foo foo) {
DeferredResult<Foo> remove = concurrentMap.remove(foo.getId());
remove.setResult(foo);
}
// ...
}
and I want call it in another service:
#Service
public class AnotherService {
#Autowired
FooService fooService;
public Foo bar(long id) {
// some logic
Foo foo = fooService.fetchFoo(id).getResult();
// another logic which depends on received foo
// there I need wait for result of fetchFoo method
return foo;
}
}
Can you tell me please how to ensure this behaviour? Thank you in advice.
You can use CountDownLatch for synchronize. Example:
public class Main {
public static void main(String[] args) throws InterruptedException {
System.out.println(1);
CountDownLatch latch = new CountDownLatch(1);
getResult()
.setResultHandler(result -> {
System.out.println(2 + " " + result);
latch.countDown();
});
latch.await();
System.out.println(3);
}
public static DeferredResult<String> getResult() {
DeferredResult<String> result = new DeferredResult<>();
new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
result.setResult("Hello");
})
.start();
return result;
}
}

Is there a pattern to execute a chain of methods based on the result of the previous in Java?

The use case is there is a set of methods which need to be executed based on whether the previous one has returned true or not.
For example:
class Test {
boolean method1() {...}
boolean method2() {...}
boolean method3() {...}
...
void callAll() {
if(method1()) {
if(method2() {
if(method3() {
...
}
}
} else {
error();
}
}
}
There has to be an else for all the ifs.
Is there a better way of handling this scenario?
I would just do it like this:
void callAll(){
if(method1() && method2() && method3()){
// all passed
} else {
error();
}
}
Java short-circuits the && logical operation so failure in a previous method here will prevent running the next one.
If in error() you need to know which of the methods failed, you could declare an error message field for storing the information within the class and set its value corresponding the failure:
private String errorMessage;
//...
boolean method2() {
// something went wrong
errorMessage = "Failed to do method2 stuff";
}
Are more elegant way to achieve the same would be to use the Chain of responsibility design pattern and encapsulate the boolean methods in their own handler objects. Doing this would however require more refactoring to the code you currently have and more information about your specific use case.
It's easy enough to write your own varargs method to do this:
public static void run(Supplier<Boolean>... methods) {
for (Supplier<Boolean> method : methods) {
if (!method.get()) return;
}
}
Sample usage:
run(this::method1, this::method2, this::method3);
You can use some form of Observable pattern for these kind of thins too. In most normal cases it seems a bit silly to implement it but otherwise a great way to decouple code from control structures if you have a lot of these. Note that ObservableBoolean is an Android class, but just showing the logic here:
ObservableBoolean a = new ObservableBoolean();
ObservableBoolean b = new ObservableBoolean();
public void call() {
a.addOnPropertyChangedCallback(new OnPropertyChangedCallback() {
#Override
public void onPropertyChanged(android.databinding.Observable sender, int propertyId) {
method2();
}
});
b.addOnPropertyChangedCallback(new OnPropertyChangedCallback() {
#Override
public void onPropertyChanged(android.databinding.Observable sender, int propertyId) {
//..you end the "chain" here
}
});
method1();
}
void method1() {
if(true) {
a.set(true);
}
else {
b.set(false);
}
}
void method2() {
if(true) {
b.set(true);
}
else {
b.set(false);
}
}
I use this technique - although some would find it odd.
boolean method1() {
System.out.println("method1");
return true;
}
boolean method2() {
System.out.println("method2");
return false;
}
boolean method3() {
System.out.println("method3");
return true;
}
void callAll() {
boolean success = method1();
success = success ? method2() : success;
success = success ? method3() : success;
if (success) {
System.out.println("Success");
} else {
System.out.println("Failed");
}
}
I could suggest you to use RX approach, with rxjava it should look like
public boolean test1() {
Log.d("TESTIT", "test1 called");
return true;
}
public boolean test2() {
Log.d("TESTIT", "test2 called");
return true;
}
public boolean test3() {
Log.d("TESTIT", "test3 called");
return false;
}
public boolean test4() {
Log.d("TESTIT", "test4 called");
return true;
}
public boolean elseMethod(boolean result) {
if (result) return true;
else {
Log.d("TESTIT", "ELSE");
}
return false;
}
public void chainedCallback() {
Observable.just(test1())
.filter(this::elseMethod)
.flatMap(aBoolean -> Observable.just(test2()))
.filter(this::elseMethod)
.flatMap(aBoolean -> Observable.just(test3()))
.filter(this::elseMethod)
.flatMap(aBoolean -> Observable.just(test4()))
.filter(this::elseMethod)
.subscribe();
}
call for chainedCallback() will print
test1 called
test2 called
test3 called
ELSE
You define a class that holds an action (calling one of the methods) and with a corresponding failure handler (the else block of an if call)
public static class ActionWithFailureHandler {
private Supplier<Boolean> action;
private Runnable failureHandler;
public ActionWithFailureHandler(Supplier<Boolean> action, Runnable failureHandler) {
this.action = action;
this.failureHandler = failureHandler;
}
//Getters for the instance variables
}
You make a list of the above and call each of the actions till one of the following happens
One of the actions fails (i.,e one of the method returns false). In that case, you need to execute the failureHandler corresponding to that action.
All actions pass. In this case, execute the successHandler (the logic that you execute when all methods return true).
private static void callAll(List<ActionWithFailureHandler> actionWithFailureHandlers, Runnable successHandler) {
actionWithFailureHandlers.stream()
.filter(actionWithFailureHandler -> !actionWithFailureHandler.getAction().get())
.findFirst() //Find first failing action
.map(ActionWithFailureHandler::getFailureHandler)
.orElse(successHandler)
.run(); //You might be running either the successHandler or the failureHandler for the first failed action
}
Driver code:
public static void main(String[] args) {
Test test = new Test();
List<ActionWithFailureHandler> actionWithFailureHandlers = com.google.common.collect.ImmutableList.of(
new ActionWithFailureHandler(test::method1, () -> System.out.println("Method 1 returned false")),
new ActionWithFailureHandler(test::method2, () -> System.out.println("Method 2 returned false")),
new ActionWithFailureHandler(test::method3, () -> System.out.println("Method 3 returned false"))
);
callAll(actionWithFailureHandlers, () -> System.out.println("All returned true"));
}
Exception firstly comes to my mind, but see the link below to learn more about its performance hit.
Original answer. I would do..
public class MyException extends Exception
{
}
public void doAll()
{
try
{
method1();
method2();
method3();
}catch (MyException e)
{
error();
}
}
And let's assume that method1, method2, and method3 throws MyException when it fails.
Though it does not fit your question, it is a good pattern to use Exceptions.
public class Helper
{
public Helper(Method m)
{
this.method=m;
}
public void Do() throws MyException
{
if(method.invoke()==false)
throw new MyException ();
}
}
Using this class,
public void doAll()
{
Helper [] helpers={new Helper(this::method1), new Helper(this::method2), new Helper (this::method3)};
try
{
for(Helper helper:helpers)
{
helper.Do();
}
}catch (MyException e)
{
error();
}
}
But
according to the comment of #dilix and the link, it can be a performance-expensive strategy.
So let's use them only for their purpose.

Run method inside a method in java

I'm sending more than 1 request to a web service, below there is an example of that requests. Its important for my application to get the answer from the web service so if there is an exception application will try couple of times to get the answer.
Because of that getting something simple like
deviceList = serviceAdapter.getDevices(); is turn into below code.
boolean flag = true;
int counter = 1;
List<Device> deviceList = null;
while (flag) {
try {
deviceList = serviceAdapter.getDevices();
flag = false;
} catch (Exception e) {
try {
if (counter == 5) {
System.out.println("Timeout Occured!");
flag = false;
} else {
Thread.sleep(1000 * counter);
counter++;
}
} catch (InterruptedException e1) {
}
}
}
And in my application i have lots of requests which means there will be more ugly codes. Is there a way where i will call my request methods as parameter for another method something like this:
deviceList = wrapperMethod(serviceAdapter.getDevices());
Problem is there will be different type of requests, so they will return different type objects (list,array,string,int) and their paramaters will change. Is there a suitable solution in java for this problem?
You can pass a Supplier<T> to the wrapperMethod:
public static <T> T wrapperMethod (Supplier<T> supp) {
boolean flag = true;
int counter = 1;
T value = null;
while (flag) {
try {
value = supp.get();
flag = false;
} catch (Exception e) {
try {
if (counter == 5) {
System.out.println("Timeout Occured!");
flag = false;
} else {
Thread.sleep(1000 * counter);
counter++;
}
} catch (InterruptedException e1) {
}
}
}
}
And call it with:
List<Device> deviceList = wrapperMethod (() -> serviceAdapter.getDevices());
I'm afraid, though, that it will limit the methods you call within the lambda expression to throw only RuntimeExceptions.
You can use some command implementation to execute some specific codes :
Here is a simple example of a command
interface Command{
void run();
}
And a couple of implementations :
class SayHello implements Command{
#Override
public void run() {System.out.println("Hello World");}
}
class KillMe implements Command{
public void run() { throw new RuntimeException();};
}
All we have to do to execute those method is to receive an instance of Command and run the method :
public static void execCommand(Command cmd) {
cmd.run();
}
And to use this
public static void main(String[] args) {
execCommand(new SayHello());
execCommand(new KillMe());
}
Hello World
Exception in thread "main" java.lang.RuntimeException
It also accepts lambda expression :
execCommand(() -> System.out.println("Say goodbye"));
And method reference :
public class Test{
public static void testMe() {
System.out.println("I work");
}
}
execCommand(Test::testMe);
Note that I didn't specify that this could throw Exception so I am limited to unchecked exception like RuntimeException but of course void run() throws Exception could be a solution. That way you can do what ever you want.
Full example (with exceptions) :
public class Test {
public static void main(String[] args) {
try {
execCommand(new SayHello());
execCommand(() -> System.out.println("Say goodbye"));
execCommand(Test::testMe);
execCommand(new KillMe());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void testMe() throws IOException{
System.out.println("I work");
}
public static void execCommand(Command cmd) throws Exception {
cmd.run();
}
}
interface Command{
void run() throws Exception;
}
class SayHello implements Command{
#Override
public void run() {System.out.println("Hello World");}
}
class KillMe implements Command{
public void run() { throw new RuntimeException();};
}
Output:
Hello World
Say goodbye
I work
Exception in thread "main" java.lang.RuntimeException
at main.KillMe.run(Test.java:39)
at main.Test.execCommand(Test.java:25)
at main.Test.main(Test.java:17)
You can use #RetryOnFailure annotation from jcabi-aspects
Create a wrapper method then annotate it to enable auto retry upon Exception
As an example:
#RetryOnFailure(attempts = 5)
List<Device> retryWhenFailed(ServiceAdapter serviceAdapter) throws Exception {
return serviceAdapter.getDevices();
}
This solution uses Generics to be able to handle different Object with most of the same code and a Runnable to execute the fetching.
With this solution, you would need only to write the different adapters extending from ServiceAdapter<T extends Fetchable> to implement the logic to fetch the data for each different class (which would have to implement Fetchable).
Define an interface that abtracts the objects that can be fetched by the different services.
package so50488682;
public interface Fetchable {
}
The ojbect that are to be retrieved implement this interface so you can use the same code for different classes.
package so50488682;
public class Device implements Fetchable{
private String id;
public Device(String id) {
this.id = id;
}
public String toString() {
return "I am device " + id;
}
}
Define an abstract ServiceAdapter that the different service adapters will extend to implement the logic for each kind of object to be retrieved. We add throws Exception to the get() method so this method cand just delegate the exception handling to the FetcherService and decide if it should retry or fail.
package so50488682;
import java.util.List;
public abstract class ServiceAdapter<T extends Fetchable> {
public abstract List<T> get() throws Exception;
}
This is an example of an implementation done to get objects of class Device.
package so50488682;
import java.util.ArrayList;
import java.util.List;
public class DeviceServiceAdapter extends ServiceAdapter<Device>{
#Override
public List<Device> get() throws Exception{
List<Device> rtn = new ArrayList<>();
// fetch the data and put it into rtn, this is a mock
Device d = new Device("1");
rtn.add(d);
d = new Device("2");
rtn.add(d);
d = new Device("3");
rtn.add(d);
//
return rtn;
}
}
Finally this is a generic solution to run the different service adapters.
public class FetcherService<T extends Fetchable> implements Runnable{
List<T> result = new ArrayList<>();
ServiceAdapter<T> serviceAdapter;
#Override
public void run() {
boolean flag = true;
int counter = 1;
while (flag) {
try {
result = serviceAdapter.get();
flag = false;
} catch (Exception e) {
try {
if (counter == 5) {
System.out.println("Timeout Occured!");
flag = false;
} else {
Thread.sleep(1000 * counter);
counter++;
}
} catch (InterruptedException e1) {
throw new RuntimeException("Got Interrupted in sleep", e);
}
}
}
}
public List<T> getResult() {
return result;
}
public void setResult(List<T> result) {
this.result = result;
}
public void setAdapter(ServiceAdapter<T> adapter) {
this.serviceAdapter = adapter;
}
}
From the main or calling program it work like this:
package so50488682;
import java.util.List;
public class SO50488682 {
public static void main(String args[]) {
try {
DeviceServiceAdapter deviceServiceAdapter = new DeviceServiceAdapter();
FetcherService<Device> deviceFetcherService = new FetcherService<>();
deviceFetcherService.setAdapter(deviceServiceAdapter);
deviceFetcherService.run();
List<Device> devices = deviceFetcherService.getResult();
for(Device device : devices) {
System.out.println(device.toString());
}
}catch(Exception e) {
System.out.println("Exception after retrying a couple of times");
e.printStackTrace();
}
}
}

How can i know threads jobs are done?

In class B how can i know jobs of threads are finished? In after properties some worker are running. In class B, I need to know if worker are done?
public class A implements InitializingBean{
public void method1(){
...
}
#Override
public void afterPropertiesSet() throws Exception {
System.out.print("test after properties set");
// send threads to executorService
ExecutorService executorService = Executors
.newFixedThreadPool(4);
for (int i = 0; i < 4; i++) {
Worker worker = new Worker();
executorService.submit(worker);
}
}
}
public class Worker implements Callable<Void>{
#Override
public void call(){
...
}
}
public class B{
public void methodB(){
A a = new A();
a.method1();
///Here How can i know the job of the workers are finished?
}
}
Use a listener/callback pattern to have the thread report completion to a listener. This simple example should show the process:
public interface ThreadCompleteListener {
void workComplete();
}
public class NotifyingThread extends Thread {
private Set<ThreadCompleteListener> listeners;
// setter method(s) for adding/removing listeners to go here
#Override
public void run() {
// do stuff
notifyListeners();
}
private void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.workComplete(); // notify the listening class
}
}
}
in your listening class:
NotifyingThread t = new NotifyingThread();
t.addListener(new ThreadCompleteListener() {
void workComplete() {
// do something
}
});
t.start();
You could use a Future implementation for your thread. It provides a Future#isDone()
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#isDone()
In general, it is usually more useful to be notified via a callback when jobs complete. However, since others have posted answers which follow that model, I'll instead post a solution that simply allows you to poll and ask whether the jobs are finished, in case this is what fits the needs of your application better.
public static interface InitializingBean{
public void afterPropertiesSet() throws Exception;
}
public static class A implements InitializingBean{
private List<Future<Void>> submittedJobs = Collections.synchronizedList(new ArrayList<Future<Void>>());
public void method1(){
//do stuff
}
#Override
public void afterPropertiesSet() throws Exception {
System.out.print("test after properties set");
// send threads to executorService
ExecutorService executorService = Executors
.newFixedThreadPool(4);
synchronized (submittedJobs) {
for (int i = 0; i < 4; i++) {
Worker worker = new Worker();
submittedJobs.add(executorService.submit(worker));
}
}
}
/**
* Allows you to poll whether all jobs are finished or not.
* #return
*/
public boolean areAllJobsFinished(){
synchronized (submittedJobs) {
for(Future<Void> task : submittedJobs){
if(!task.isDone()){
return false;
}
}
return true;
}
}
}
public static class Worker implements Callable<Void>{
#Override
public Void call(){
//do worker job
return null; //to satisfy compiler that we're returning something.
}
}
public static class B{
public void methodB(){
A a = new A();
a.method1();
if(a.areAllJobsFinished()){
System.out.println("Congrats, everything is done!");
} else {
System.out.println("There's still some work being done :-(");
}
}
}
If you'd like to wait in that thread that starts the ExecutorService, you can actually use the awaitTermination method.
At the end of you afterPropertiesSet method, you should add:
executorService.shutdown();
After this you then add:
executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)
This causes the thread to wait for all the executorService's tasks to be done and then continues. So place any code you want to execute after the call to awaitTermination.

Create a java thread that runs on a timer but can be awaken at any time

I would like to create a class that runs something (a runnable) at regular intervals but that can be awaken when needed. If I could encapsulate the whole thing I would like to expose the following methods:
public class SomeService implements Runnable {
public run() {
// the code to run at every interval
}
public static void start() { }
public static void wakeup() { }
public static void shutdown() { }
}
Somehow I've gotten this far. But I'm not sure if this is the correct approach.
public class SomeService implements Runnable {
private static SomeService service;
private static Thread thread;
static {
start();
}
private boolean running = true;
private SomeService() {
}
public void run() {
while (running) {
try {
// do what needs to be done
// perhaps peeking at a blocking queue
// or checking for records in a database
// trying to be independent of the communication
System.out.println("what needs to be done");
// wait for 15 seconds or until notify
synchronized (thread) {
try {
thread.wait(15000);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static void start() {
System.out.println("start");
service = new SomeService();
thread = new Thread(service);
thread.setDaemon(true);
thread.start();
}
public static void wakeup() {
synchronized (thread) {
thread.notify();
}
}
public static void shutdown() {
synchronized (thread) {
service.running = false;
thread.interrupt();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("shutdown");
}
public static void main(String[] args) throws IOException {
SomeService.wakeup();
System.in.read();
SomeService.wakeup();
System.in.read();
SomeService.shutdown();
}
}
I'm concerned that the variables should be declared volatile. And also concerned that I should check in the "what needs to be done part" for thread.isInterrupted(). Does this seem like the right approach? Should I translate this to executors? How can I force a run on a scheduled executor?
EDIT
After experimenting with the executor, it seems that this approach seems reasonable. What do you think?
public class SomeExecutorService implements Runnable {
private static final SomeExecutorService runner
= new SomeExecutorService();
private static final ScheduledExecutorService executor
= Executors.newSingleThreadScheduledExecutor();
// properties
ScheduledFuture<?> scheduled = null;
// constructors
private SomeExecutorService() {
}
// methods
public void schedule(int seconds) {
scheduled = executor.schedule(runner, seconds, TimeUnit.SECONDS);
}
public void force() {
if (scheduled.cancel(false)) {
schedule(0);
}
}
public void run() {
try {
_logger.trace("doing what is needed");
} catch (Exception e) {
_logger.error("unexpected exception", e);
} finally {
schedule(DELAY_SECONDS);
}
}
// static methods
public static void initialize() {
runner.schedule(0);
}
public static void wakeup() {
runner.force();
}
public static void destroy() {
executor.shutdownNow();
}
}
For starters - you probably don't want to implement Runnable yourself; you should take in a Runnable. You should only implement Runnable if you expect your class to be passed to others to execute.
Why not just wrap a ScheduledExecutorService? Here's a quick (very poor, but ought to be functional) implementation.
public class PokeableService {
private ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
private final Runnable codeToRun;
public PokeableService (Runnable toRun, long delay, long interval, TimeUnit units) {
codeToRun = toRun;
service.scheduleAtFixedRate(toRun, delay, interval, units);
}
public void poke () {
service.execute(codeToRun);
}
}
The variables do not need to be volatile since they are read and modified in a synchronized block.
You should use a different object for the lock then the thread, since the Thread class does it's own synchronization.
I would recommend using a single threaded ScheduledExecutorService and remove sleeping. Then if you want to run the task during the current sleep period, you can submit it to the executor again for a single time run. Just use the execute or submit methods in ExecutorService which ScheduledExecutorService extends.
About checking for isInterrupted, you should do this if the do work portion can take a lot of time, can be cancelled in the middle, and is not calling methods that block and will throw an interrupted exception any ways.
Using wait/notify should be a more efficient method. I also agree with the suggestion that using 'volatile' is not necessary and synchronizing on an alternative object would be wise to avoid conflicts.
A few other suggestions:
Start the thread elsewhere, starting from a static block is not good practice
Putting the execute logic in an "execute()" method or similar would be desirable
This code implements the above suggestions. Note also that there is only the one thread performing the SomeService execution logic and that it will occur INTERVAL milliseconds after the time it last completed. You should not get duplicate executions after a manually triggered wakeUp() call.
public class SomeService implements Runnable {
private static final INTERVAL = 15 * 1000;
private Object svcSynchronizer = new Object();
private boolean running = true;
private SomeService() {
}
public void run() {
while (running) {
try {
// do what needs to be done
// perhaps peeking at a blocking queue
// or checking for records in a database
// trying to be independent of the communication
System.out.println("what needs to be done");
// wait for 15 seconds or until notify
try {
svcSynchronizer.wait(INTERVAL);
} catch (InterruptedException e) {
// ignore interruptions
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void wakeUp() {
svcSynchronizer.notifyAll();
}
public void shutdown() {
running = false;
svcSynchronizer.notifyAll();
}
}

Categories

Resources