synchronise a method with runnable executing some async calls - java

I am working with a init() that need to be synchronise. But I have to run some set of instructions in init() which has to execute on main thread. So I created a runnable to add this instruction. And those instructions has some async calls.
So I am exploring efficient ways to block the init() untill all the instructions completes successfully.
Static void init() {
new Handler(context.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// doing some async calls
}
}
}

You need to synchronize the init() method and then use CompletionService to wait for Future to complete. Like so:
public synchronized void init() throws InterruptedException {
Executor executor = Executors.newFixedThreadPool(4);
CompletionService<String> completionService = new ExecutorCompletionService<String>(executor);
// 4 tasks
for (int i = 0; i < 4; i++) {
completionService.submit(new Callable<String>() {
public String call() {
return "i am an async task finished";
}
});
}
int received = 0;
boolean errors = false;
while (received < 4 && !errors) {
Future<String> resultFuture = completionService.take(); // blocks if none available
try {
String result = resultFuture.get();
System.out.println(result);
received++;
} catch (Exception e) {
errors = true;
/// some acceptable error handling;
}
}
}
I have taken the code from this thread and adopted it for your needs. Don't forget to handle InterruptedException properly like described here.

Related

How to stop working ScheduledExecutorService?

In my project I have a chart which can turn into an animation depending on if we click Start or Stop button. I can make it start, but I don't know how to stop it. Method shutdownNow() gives no result. How can I do this? Here is my code
public class Animation extends JPanel{
// initializations
ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
Animation(String s){
// initialization of chart and adding XYSeries
this.add(chartPanel);
}
public void go() {
scheduler.scheduleAtFixedRate( (new Runnable() {
#Override
public void run() {
double first;
l = dataset.getSeries();
while(true) {
first = (double)l.get(0).getY(0);
for (int k = 0; k < l.get(0).getItemCount(); k++) {
if (k + 1 < l.get(0).getItemCount()) l.get(0).updateByIndex(k, l.get(0).getY(k+1));
else l.get(0).updateByIndex(k, first);
}
}
}
}), 0, 5, MILLISECONDS);
}
public void stop() {
scheduler.shutdownNow();
}
}
As per java docs how shutdownNow() works like below.
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via {#link Thread#interrupt}, so any a task that fails to
respond to interrupts may never terminate.
So, it will set interrupted flag true, so you need to correctly manage the InterruptedException and / or explicitly check Thread.currentThread().isInterrupted(). You can use below code to stop your current running inputted thread.
while (!Thread.currentThread().isInterrupted()) {
// your code here
}
(!Thread.currentThread().isInterrupted())
may be a solution
but personally i would:
extract runner in method
stop runner by flipping a boolean
call scheduler.shutdownNow(); when needed (on close JPanel?)
example:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
boolean running;
public void setup() {
scheduler.scheduleAtFixedRate(runner(), 0, 5, TimeUnit.MILLISECONDS);
}
private Runnable runner() {
return () -> {
while (running) {
try {
//DO YOUR STUFF HERE
System.err.println("RUNNING");
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
}
public void go() {
running = true;
}
public void stop() {
running = false ;
}
public void shutdown() {
scheduler.shutdownNow();
}
public static void main(String[] args) throws InterruptedException {
Demo tasks = new Demo();
tasks.setup();
for (int i = 1; i <= 5; i++) {
System.err.println("GO FOR IT " + i);
tasks.go();
Thread.sleep(2000);
tasks.stop();
Thread.sleep(1000);
}
tasks.shutdown();
}

Java: How to put thread back to sleep INDEFINITELY after interrupt?

I am writing Java software, that has a single thread, which listens to external buttons being pressed. If the button is pressed, the thread informs other threads, but otherwise it just sleeps.
My model is to use interrupt-driven design. Ideally I would like to make
a thread sleep as long as no button is pressed. When the button is pressed I would like the thread to do some work and go back to sleep.
Could anyone confirm / correct the following implementation?
// This is a code that interrupt-driven thread will execute
public void run() {
while (true) {
try {
Thread.sleep(1000); // Sleeps only for 1s. How to sleep indefinitely?
} catch (InterruptedException exception) {
process(exception); // Doing some work
// then going back to sleep using the while loop
}
}
}
Also, after each button click in the terminal I get a message
I/O exception raised from stop()
What does this message mean (i.e why is it printed if I catch the exception)? Can I avoid the terminal to print it?
It is generally considered a code smell if you use exceptions to control your program flow.
The correct solution to this problem is to use a BlockingQueue of events that the event handler reads from. This is commonly called a producer/consumer.
public class TwoThreads {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test");
new TwoThreads().test();
}
// The end of the list.
private static final Integer End = -1;
static class Producer implements Runnable {
final BlockingQueue<Integer> queue;
public Producer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
try {
for (int i = 0; i < 1000; i++) {
queue.add(i);
Thread.sleep(1);
}
// Finish the queue.
queue.add(End);
} catch (InterruptedException ex) {
// Just exit.
}
}
}
static class Consumer implements Runnable {
final BlockingQueue<Integer> queue;
public Consumer(BlockingQueue<Integer> queue) {
this.queue = queue;
}
#Override
public void run() {
boolean ended = false;
while (!ended) {
try {
Integer i = queue.take();
ended = i == End;
System.out.println(i);
} catch (InterruptedException ex) {
ended = true;
}
}
}
}
public void test() throws InterruptedException {
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
// Start it all going.
pt.start();
ct.start();
// Wait for it to finish.
pt.join();
ct.join();
}
}
Don't let yourself be confused by how much code this is - most of it is just wrapping. The core functionality is:
At start - create a BlockingQueue and share it between the two threads.
BlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
Thread pt = new Thread(new Producer(queue));
Thread ct = new Thread(new Consumer(queue));
When an event happens, post to the queue.
queue.add(i);
The event handler feeds off the queue.
while (!ended) {
try {
Integer i = queue.take();
Note that take here will block until an event is posted or an interrupt occurrs.
You can use
Thread.sleep(Long.MAX_VALUE); // more than the life of your computer
or
synchronized(this) {
wait();
}
or this wake on interrupt but doesn't throw an exception
LockSupport.park();
However a more elegant solution is likely to be to use an ExecutorService is designed to be a sleeping thread pool which wakes when you give it work to do.
ExecutorsService executor = Executors.newSingleThreadExecutor();
// when you want it to do something
executor.submit(this::process);
Note: you should consider how you want to handle exceptions. In the example in your question, an exception or error will kill the thread and it will stop running. In my example it won't kill the thread pool but the actual exception could be lost. For this reason I suggest you write it like this.
executor.submit(() -> {
try {
process();
} catch(Throwable t) {
LOGGER.warning(t);
}
});
Note: instead of just calling process and it having to figure out what you want to do you can write it like this.
doSomething(string, number, pojo);
That way you can see what data you expect the background thread to work on.
For comparison, here is the TwoThread example using the current thread as a producer and an Executor Service.
public class TwoThreadsJava5 {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test - Java 5.0 style");
ExecutorService executor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 1000; i++) {
final int finalI = i;
executor.submit(() -> {
try {
System.out.println(finalI);
} catch (Throwable t) {
t.printStackTrace();
}
});
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.MINUTES);
}
}
And in Java 8 you could write
public class TwoThreadsJava8 {
public static void main(String args[]) throws InterruptedException {
System.out.println("TwoThreads:Test - Java 8 style");
IntStream.range(0, 1000)
.parallel()
.forEach(System.out::println);
}
}

Synchronized keyword doesn't work

package threadShareResource1;
public class NonSynchro1 {
private int sum = 0;
public static void main(String[] args) {
NonSynchro1 n = new NonSynchro1();
n.task();
System.out.println(n.getSum());
}
public synchronized void sumAddOne(){
sum++;
}
public void task(){
for (int i = 0; i < 100; i++) {
new Thread(new Runnable(){
#Override
public void run() {
sumAddOne();
}
}).start();
/* try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
} */
}
}
public int getSum() {
return sum;
}
}
Without the commented part of code, the program has data corruption, which is not 100 every time I run it. But I thought the synchronized keyword should acquires a lock on the sumAddOne method, which is the critical region of my program, allowing one thread accessing this method every time.
I've try to use ExecutorService as well, but it doesn't give 100 all the runs.
public void task(){
ExecutorService s = Executors.newCachedThreadPool();
for (int i = 0; i < 100; i++) {
s.execute(new Thread(new Runnable(){
#Override
public void run() {
sumAddOne();
}
}));
}
s.shutdown();
while(!s.isTerminated()){}
}
In Task(), you start 100 threads (which is a lot) and each one is to add 1 to sum.
But when Task is done all you know is that 100 threads are in some process of having started. You don't block before calling println(), so how do you know all the threads have completed?
The sleep probably "prevents the corruption" just because it gives the system time to finish launching all the threads.
Beyond that you are using Synchronized correctly. Any place multiple threads may write to the same variable you need it and, in general (simplifying), you don't need it if you are only reading.
Synchronised keyword is used correctly, the problem is that you are not waiting for the threads to finish. Here is a possible solution:
public class NonSynchro1 {
private static final ExecutorService executorService = Executors.newCachedThreadPool();
private int sum = 0;
public static void main(String[] args) {
NonSynchro1 n = new NonSynchro1();
n.task();
System.out.println(n.getSum());
executorService.shutdown();
}
public synchronized void sumAddOne() {
sum++;
}
public void task() {
List<Callable<Object>> callables = new ArrayList<>();
for (int i = 0; i < 100; i++) {
callables.add(() -> {
sumAddOne();
return null;
});
}
List<Future<Object>> futures;
try {
futures = executorService.invokeAll(callables);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
futures.forEach(future -> {
try {
future.get();
} catch (ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
});
}
public int getSum() {
return sum;
}
}
First we create a list of callables - a list of functions that will be executed in parallel.
Then we invoke them on the executor service. newCachedThreadPool I have used here, by default has 0 threads, it will create as many as necessary to execute all passed callables, the threads will be killed after being idle for a minute.
Finally, in the for-each loop we resolve all futures. get() call will block until the function was executed by the executor service. It will also throw exception if it was thrown inside the function (without calling get() you would not see such exception at all).
Also, it is a good idea to shutdown the executor service when you want to terminate the program gracefully. In this case, it is just executorService.shutdown() at the end of main method. If you don't do this, the program will terminate after a minute when idle threads are killed. However, if different executor service, threads might not be killed when idle, in which case the program would never terminate.
Just for completeness sake: Here's a solution showing how the original program can be made to wait for all threads to finish by joining them:
for (Thread t : n.task())
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
which requires task to return the threads it creates. In this case we don't need to complicate things with caching managers or collections: a simple array will do. Here's the complete class:
public class TestSynchro1 {
private int sum = 0;
public synchronized void sumAddOne() {
sum++;
}
public Thread[] task(int n) {
Thread[] threads = new Thread[n];
for (int i = 0; i < n; i++) {
(threads[i] = new Thread(new Runnable() {
#Override
public void run() {
sumAddOne();
}
})).start();
}
return threads;
}
public static void main(String[] args) {
TestSynchro1 n = new TestSynchro1();
for (Thread t : n.task(100))
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(n.sum);
}
}

Stop ExecutorService threads when one thread fails. & return the exception

If any of the submitted thread is throwing exception its not returning the exception.
I want to write a piece of code for my project where in if any of the thread execution is failed it should throw the exception there & it should stop all the running & scheduled threads.
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
Thread t = new Thread(new MyObject());
executorService.submit(t);
}
I wrote MyObject like this..,
public class MyObject implements Runnable {
public void run() {
throw new NullPointerException("Sample NullPointerException");
}
}
Is this the correct implementation for my goal...?????
i want to achieve that goal please give me some pointers.
Thanks In Advance....!!
Here is something you can consider about. Here I am using CallableTask instead of Thread.
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
Set<Future<Void>> futureSet = new HashSet<Future<Void>>();
for (int i = 0; i < 9; i++) {
CallableTask1 task = new CallableTask1();
futureSet.add(executorService.submit(task));
}
CallableTask2 task2 = new CallableTask2();
futureSet.add(executorService.submit(task2));
boolean flag = false;
for (Future<Void> future : futureSet ) {
try {
future.get();
} catch (InterruptedException e) {
System.out.println("Interrupted");
} catch (ExecutionException e) {
System.out.println("Exception thrown from the thread");
flag = true;
break;
}
}
if(flag) {
for (Future<Void> future : futureSet) {
future.cancel(true);
}
}
}
Here I am using two classes to demonstrate this is working. When one task throw an exception the forever running task is also stop running.
class CallableTask1 implements Callable<Void> {
#Override
public Void call() throws Exception {
throw new NullPointerException("Sample NullPointerException");
}
}
class CallableTask2 implements Callable<Void> {
#Override
public Void call() throws Exception {
while (true){
System.out.println("THIS IS RUNNING");
Thread.sleep(5000);
}
}
}
But this has it's own limitations. This code will wait for it's turn to throw an exception because of "future.get()" executed sequentially.
Best case : Throw an exception in first future.get() and other tasks will be cancelled.
Worst case : Throw an exception in the last future.get() and by the time throw an exception all other tasks done with execution.
Optimizing : Identify the tasks that can throw an exception and wait for those tasks only to cancel all the other tasks.
If your run methods has while in it then best way share a flag and break on it. Check this answer for more information.

How do I test the completion of threads created under my testmethod in JUnit

I have a method createThreads which spawns few new threads. Each of the newly created thread does some work. If I invoke the method `createThreads' in junit, how can i ensure that all the newly spawned threads have also completed successfully.
I am currently calling as below
#Test
public void test() {
createThreads(); // Does not wait until the newly created threads also finish.
}
public void createThreads()
{
ExecutorService executorService = Executors
.newFixedThreadPool(numThreads);
for (int i = 0; i < numThreads; i++) {
executorService.execute(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I have completed execution " + Thread.currentThread().getName());
}
});
}
Note that I cannot modify createThreads
a bit odd but..
you can probably get all the runing threads
through Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
then filter it to identify the thread from the executor service.
then do a .join() on each of those threads.
as i said, a bit odd but it should fit your needs ...
try running this, you'll see that they are quite easy to identify :
public static void main(String[] args) {
int nb = 3;
ExecutorService executorService = Executors.newFixedThreadPool(nb);
for (int i = 0; i < nb; i++) {
executorService.execute(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("I have completed execution " + Thread.currentThread().getName());
}
});
}
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread t : threadSet) {
System.out.println(t.getName());
}
}
sorry for a 2nd answer not possible to add such a long code in comment

Categories

Resources