java.util.concurrent: Transition from Runnable to Executor interface - java

I am writing a JUnit test case for a DSL, and I need to ensure that the method under test does never end (as in this question).
The provided solution is fine, but I would like to use the "new" Executor interface (Java 5.0 onwards):
#Test
public void methodDoesNotReturnFor5Seconds() throws Exception {
Thread t = new Thread(new Runnable() {
public void run() {
methodUnderTest();
}
});
t.start();
t.join(5000);
assertTrue(t.isAlive());
// possibly do something to shut down methodUnderTest
}
How can I translate the above code from the "old" Thread/Runnable interface to the "new" ExecutorService/Executor interface?

Future<?> future = Executors.newSingleThreadExecutor().submit(new Runnable() {
public void run() {
methodUnderTest();
}
});
try {
future.get(5, TimeUnit.SECONDS);
fail("The task has completed before 5 seconds");
}
catch (TimeoutException e) {
// expected
}

Related

Scheduler works incorrect in unit testing

I need to collect data from a public API. I want to collect it daily or twice a day.
public class AlphavantageStockRequestDispatcher {
public static void startAlphavantageStockScraper(int timeInterval) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable getStockList =
new Runnable() {
#Override
public void run() {
List<AlphavantageStock> stocks = AlphavantageStockRequest.getStockPrices(); //Method contains requests
StockDao<AlphavantageStock> dao = new JpaAlphavantageStockDao();
for (AlphavantageStock stock : stocks) {
dao.save(stock);
}
}
};
scheduler.scheduleAtFixedRate(getStockList, 0, timeInterval, TimeUnit.HOURS);
}
}
The problem is when I start it from the same class (just added main method and invoked startAlphavantageStockScraper(1); it works fine. But when I want to test it via JUnit it's not working (test class is in symmetric package name but test subfolder):
public class AlphavantageStockRequestDispatcherTest {
#Test
public void startDispatcher_TwoFullCycles_WithOneHourIntervalBetween() {
AlphavantageStockRequestDispatcher.startAlphavantageStockScraper(1);
}
}
While debugging I found out that in unit test execution a program reaches public void run() line then skips it. So there's no error. Program ends up correctly but does nothing useful.
Any help will be appreciated.
This is how asynchronous programming works. In the AlphavantageStockRequestDispatcher class you've just submitted a task but you have to wait for it's completed. There are several ways to handle this situation. I prefer state notification using java.util.concurrent.CountDownLatch. So some refactoring is recommended in AlphavantageStockRequestDispatcher class like this:
public class AlphavantageStockRequestDispatcher {
public static void startAlphavantageStockScraper(int timeInterval, CountDownLatch latch) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable getStockList =
new Runnable() {
#Override
public void run() {
System.out.println("worker started");
try {
Thread.sleep(10_000L);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("worker finished");
Optional.ofNullable(latch).ifPresent(CountDownLatch::countDown);
}
}
};
scheduler.scheduleAtFixedRate(getStockList, 0, timeInterval, TimeUnit.HOURS);
}
}
Now it's possible to test that.
public class AlphavantageStockRequestDispatcherTest {
#Test
void startDispatcher_TwoFullCycles_WithOneHourIntervalBetween() throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
AlphavantageStockRequestDispatcher.startAlphavantageStockScraper(1, latch);
latch.await(20, TimeUnit.SECONDS);
System.out.println("first finished - need some assertions");
}
}

Can't stop thread

I have these two methods for creating and stopping a thread. However the thread still keeps running, even after the first method is called. (I'm creating an object of the class and calling them from another class).
private Thread thread;
public void stopAlarm() {
Log.i(LOG_TAG, "stopAlarm called");
sendAlarm = false;
if (!thread.equals(null)) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void triggerAlarm() {
Runnable alarmTest = new Runnable() {
#Override
public void run() {
while (sendAlarm) {
Log.i(LOG_TAG, String.valueOf(sendAlarm));
}
}
};
thread = new Thread(Test);
thread.start();
}
When stopAlarm is called the thread is always null, although it is called after triggerAlarm is called (thread is running).
Your problem is caused by thread scope. Thread scope is created when you create a thread with same variables in the scope but you can't change these variables from outside world. Best practice for managing runnables in android is to use Handler.
Handler handler = new Handler();
Runnable alarmTest = new Runnable() {
#Override
public void run() {
Log.i(LOG_TAG, String.valueOf(sendAlarm));
handler.post(alarmTest, 5000); //wait 5 sec and run again
//you can stop from outside
}
};
after definitions, in order to start the runnable:
handler.post(alarmTest,0); //wait 0 ms and run
in order to stop the runnable:
handler.removeCallbacks(alarmTest);
EDIT: wait statement with loop
EDIT: Complete solution
Handler handler = new Handler();
Runnable alarmTest = new Runnable() {
#Override
public void run() {
Log.i(LOG_TAG, String.valueOf(sendAlarm));
handler.post(alarmTest, 5000); //wait 5 sec and run again
//you can stop from outside
}
};
public void stopAlarm() {
Log.i(LOG_TAG, "stopAlarm called");
handler.removeCallbacks(alarmTest);
}
public void triggerAlarm() {
handler.post(alarmTest,0); //wait 0 ms and run
}
Depending on your OS you may find making your thread volatile may fix this.
private volatile Thread thread;
However - there are better ways to do this. One very useful one is using a small (just one entry) BlockingQueue which is polled by the running thread.
// Use a BlockingQueue to signal the alarm to stop.
BlockingQueue<String> stop = new ArrayBlockingQueue<>(1);
public void stopAlarm() {
stop.add("Stop");
}
public void triggerAlarm() {
new Thread(() -> {
try {
while (stop.poll(1, TimeUnit.SECONDS) == null) {
// Stuff
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
Clearly you will have to manage edge cases like where someone calls stopAlarm when no alarm is running.

Java - Ideal use of wait and notify?

This code seems to work fine so far in testing. However I am new at multithreading and want to know if this code is ideal, since I know there is a lot of "donts" regarding concurrency.
Is there a better way to make an executor for queued Runnables on a single thread? This is my first time making one so I feel inclined to believe something could be better.
public class ExplosionExecutor{
private static List<Runnable> queue= new ArrayList<Runnable>();
private static Thread thread= new Thread(new Runnable() {
public void run() {
while(true){
Runnable[] queuedump;
synchronized (queue) {
if(queue.size()==0){
try {
queue.wait();
} catch (InterruptedException e){e.printStackTrace();}
}
queuedump= queue.toArray(new Runnable[0]);
queue.clear();
}
for(Runnable r : queuedump)
r.run();
}
}
}, "Nuke Explosions");
static{
thread.start();
}
public static void execute(Runnable command) {
synchronized (queue) {
queue.add(command);
queue.notify();
}
}
}
This is okay - ish.
It's best not to reinvent the wheel.
1) There are blocking queues which have methods to wait for new items and are already synchronized:
public static void main(String[] args) throws Exception {
final BlockingQueue<Runnable> r = new LinkedBlockingQueue<>();
final Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
try {
r.take().run();
} catch (InterruptedException ex) {
return;
}
}
}
});
r.add(new Runnable() {
#Override
public void run() {
//do stuff
}
});
}
2) There is the ExecutorService API which encapsulates all this behaviour:
public static void main(String[] args) throws Exception {
final ExecutorService es = Executors.newSingleThreadExecutor();
es.execute(new Runnable() {
#Override
public void run() {
//do stuff
}
});
}
3) If you want to check the success of the submitted task and/or wait for a sumbitted task to finish you cannot do that using your API. With the ExecutorService you can do this very easily.
public static void main(String[] args) throws InterruptedException {
final ExecutorService es = Executors.newSingleThreadExecutor();
final Future<?> f = es.submit(new Runnable() {
#Override
public void run() {
//do stuff
}
});
try {
//wait
f.get();
} catch (ExecutionException ex) {
//there was an exeception in the task
}
}
A final note is that the way you have implemented your code there is no way to stop the consumer thread.
In my first example you would need to manually call t.interrupt() and because of my implementation this would case the thread to exit. In the second/third examples you would need to call ExecutorService.shutdown() to stop the consumer threads.
If you do not stop the threads then your program will not exit unless they are daemon.
Why are you making your own implementation? Java has a built-in ExecutorService that can run Runnables on a single thread http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html
//runs all Runnables in a single thread, one at a time
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(runnable);
Here are few improvements... Of-course if you use BlockingQueue/ExecutorService we don't need to worry about synchronization/concurrency.
One main issue in the code is: "r.run()" instead of new Thread(r).start().
Use ConcurrentLinkedQueue data structure which is Thread safe.
You can offer to lock/notify on any static obj/class obj, need not be on the queue, as queue is already thread safe.
Queue to Array conversion is not needed. iterate for queue.poll().
Also you can also use concurrent locks API (ReentrantLock or Condition classes) instead of synchronized/wait/notify.
theexamtime.com

Standard Java pattern for wrapping a timeout around an errant process

I'm using a 3rd party function (say runThird()) that has a tendency to loop indefinitely and has no timeout facility built in. However, I can kill it (killThird()). Is there a proper way to do this (i.e. some concurrency construct)?
Here's my attempt at this:
java.lang.Thread thread = new Thread(new Runnable(){
#Override
public void run(){
try {
Thread.sleep(TIMEOUT);
} catch (java.lang.InterruptedException e){
return;
}
killThird();
}
});
thread.start();
RunThirdResult rtr = runThird();
if (thread != null){
thread.interrupt();
}
But I'm not sure I like the overhead of creating a thread, using sleep and the contrivance of interrupting the thread if runThird() returns.
Let's assume runThird() retuns Integer ...
// ... in your class ...
private ExecutorService executor = Executors.newCachedThreadPool();
//... then somewhere, where you want to call runThird()
Future<Integer> handle = executor.submit( new Callable<Integer>(){
#Override Integer call(){
return runThird(); // Assume you made it available here ...
}
}
Integer result;
try{
result = handle.get(TIMEOUT,UNIT); // TIMEOUT and UNIT declared somewhere above ...
}
catch(TimeoutException ex) {
killThird();
// HANDLE result not being set!
}
// ... use result.
I would use a ScheduledExecutorService for this. Schedule it to be killed.
volatile RunThirdResult rtr;
ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
service.schedule(new Runnable(){
public void run(){
if(rtr == null) killThird();
}
}, TIMEOUT_IN_MILLIS, TimeUnit.MILLISECONDS);
RunThirdResult rtr = runThird();
Something like that? The most interesting part is StoppableWrapper#stop(), cause graceful cancellation is a hard thing and there's no common approach for all cases. One time you need to clear filesystem, other time to close network connection, etc. In your sample, you just call interrupt(), so I assumed runThird() honors being interrupted and will take care to clean things behind itself.
class Sample {
final ExecutorService tasksExecutor = Executors.newCachedThreadPool();
class StoppableWrapper implements Runnable {
private final Runnable task;
private final CountDownLatch executed;
StoppableWrapper(Runnable task, CountDownLatch executed) {
this.task = task;
this.executed = executed;
}
void stop() {
// e.g. Thread.currentThread().interrupt()
}
#Override
public void run() {
task.run();
executed.countDown();
}
}
public void scheduleTimingOutTaskExecution(final long timeout) {
final CountDownLatch executed = new CountDownLatch(1);
final StoppableWrapper command = new StoppableWrapper(new RunThirdInstance(), executed);
tasksExecutor.execute(command);
tasksExecutor.execute(new Runnable() {
#Override
public void run() {
try {
if (!executed.await(timeout, TimeUnit.MILLISECONDS)) {
command.stop();
// additionally, you can make stop() return boolean after time-out as well and handle failure
}
} catch (InterruptedException e) {
// handle stopper exception here
}
}
});
}
}

Thread end listener. Java

Are there any Listeners in Java to handle that some thread have been ended?
Something like this:
Future<String> test = workerPool.submit(new TestCalalble());
test.addActionListener(new ActionListener()
{
public void actionEnd(ActionEvent e)
{
txt1.setText("Button1 clicked");
}
});
I know, that it is impossible to deal like this, but I want to be notified when some thread ended.
Usually I used for this Timer class with checking state of each Future. but it is not pretty way.
Thanks
There is CompletionService you can use.
CompletionService<Result> ecs
= new ExecutorCompletionService<Result>(e);
ecs.submit(new TestCallable());
if (ecs.take().get() != null) {
// on finish
}
Another alternative is to use ListenableFuture from Guava.
Code example:
ListenableFuture future = Futures.makeListenable(test);
future.addListener(new Runnable() {
public void run() {
System.out.println("Operation Complete.");
try {
System.out.println("Result: " + future.get());
} catch (Exception e) {
System.out.println("Error: " + e.message());
}
}
}, exec);
Personally, I like Guava solution better.
No. Such listener does not exist.
But you have 2 solutions.
Add code that notifies you that thread is done in the end of run() method
Use Callable interface that returns result of type Future. You can ask Future what the status is and use blocked method get() to retrieve result
Here is a geekish listener. Highly unadvisible to use but, funny and clever
Thread t = ...
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler(){
#Override
public void uncaughtException(Thread t, Throwable e) {
t.getThreadGroup().uncaughtException(t, e);//this is the default behaviour
}
protected void finalize() throws Throwable{
//cool, we go notified
//handle the notification, but be worried, it's the finalizer thread w/ max priority
}
});
The effect can be achived via PhantomRefernce better
hope you have a little smile :)
Side note: what you ask is NOT thread end, but task completion event and the best is overriding either decorateTask or afterExecute
Without adding a lot of extra code you can make a quick listener thread yourself as follows:
//worker thread for doings
Thread worker = new Thread(new Runnable(){
public void run(){/*work thread stuff here*/}
});
worker.start();
//observer thread for notifications
new Thread(new Runnable(){
public void run(){
try{worker.join();}
catch(Exception e){;}
finally{ /*worker is dead, do notifications.*/}
}).start();
You can implement Observer Pattern to report completion.
public interface IRunComplete {
public void reportCompletion(String message);
}
Let the Thread caller implement this interface.
and in run() method you call this method at the end. So now you exactly knows when this thread gonna end.
Try it. I am actually using this and it's working fine.
You have a join() method defined by Thread class for that. However, you don't have direct visibility to a thread executing your Callable in concurrency API case..
Use this Example:
public class Main {
public static void main(String[] args) {
CompletionListener completedListener = count -> System.out.println("Final Count Value: " + count);
HeavyWorkRunnable job = new HeavyWorkRunnable(completedListener);
Thread otherThread = new Thread(job);
otherThread.start();
}
static class HeavyWorkRunnable implements Runnable {
CompletionListener completionListener;
public HeavyWorkRunnable(CompletionListener completionListener) {
this.completionListener = completionListener;
}
#Override
public void run() {
int count = 0;
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Clock Tick #"+i);
count += 1;
}
if (completionListener != null) {
completionListener.onCompleted(count);
}
}
}
#FunctionalInterface
interface CompletionListener {
void onCompleted(int count);
}
}

Categories

Resources