JAVA pass a method from outside class to the ThreadPool.submit() - java

I don't have previous experience with JAVA's concurrency, but ever done the same in C#.
My task
To create a "worker" class for easy multi-threading (creating continuous threads) managing in my applications.
what i want to have as result(usage example):
Worker worker = new Worker();
worker.threadCount = 10;
worker.doWork(myMethod);
worker.Stop();
to be able to use it in any class in my app, accepting 'void' methods as 'worker.doWork(myMethod);' argument.
What did i done from my researches on question:
class Worker
package commons.Threading;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
public class Worker {
static Boolean IsRunning = true;
public static int threadCount = 2;
static ExecutorService threadPool = new ErrorReportingThreadPoolExecutor(threadCount);
public void doWork(**argument method**) throws IOException, InterruptedException {
while (IsRunning) {
threadPool.submit(new Runnable() {
**argument method**
});
Thread.sleep(1000);
}
}
public static void Stop(){
IsRunning = false;
threadPool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
threadPool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!threadPool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
threadPool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
}
ErrorReportingThreadPoolExecutor
package commons.Threading;
import java.util.concurrent.*;
public class ErrorReportingThreadPoolExecutor extends ThreadPoolExecutor {
public ErrorReportingThreadPoolExecutor(int nThreads) {
super(nThreads, nThreads,
0, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
#Override
protected void afterExecute(Runnable task, Throwable thrown) {
super.afterExecute(task, thrown);
if (thrown != null) {
// an unexpected exception happened inside ThreadPoolExecutor
thrown.printStackTrace();
}
if (task instanceof Future<?>) {
// try getting result
// if an exception happened in the job, it'll be thrown here
try {
Object result = ((Future<?>)task).get();
} catch (CancellationException e) {
// the job get canceled (may happen at any state)
e.printStackTrace();
} catch (ExecutionException e) {
// some uncaught exception happened during execution
e.printStackTrace();
} catch (InterruptedException e) {
// current thread is interrupted
// ignore, just re-throw
Thread.currentThread().interrupt();
}
}
}
public static void main(String[] args) throws InterruptedException {
// replace
// ExecutorService threadPool = Executors.newFixedThreadPool(2);
// with
ExecutorService threadPool = new ErrorReportingThreadPoolExecutor(2);
while (true) {
threadPool.submit(new Runnable() {
#Override public void run() {
System.out.println("Job is running...");
if (Math.random() < 0.5) {
int q = 1 / 0;
}
System.out.println("Job finished.");
}
});
Thread.sleep(1000);
}
}
}
So, the question is - how do i pass 'void' method from outside class here threadPool.submit(new Runnable() { here });

You could pass the Runnable itself is a parameter,
public void doWork(Runnable runnable) throws IOException, InterruptedException {
while (IsRunning) {
threadPool.submit(runnable);
Thread.sleep(1000);
}
}
Runnable is a functional interface,it has a single method run that takes no-param and returns void, and hence you can use it as a function.
Runnable runnable = new Runnable(){
public void run(){
// do work
}
};
doWork(runnable);
You can express it more concisely if you are on Java 1.8
Runnable runnable = ()->{/**do work*/};
doWork(runnable);

Related

Ending console based multi threaded program gracefully

I have the following class, I usually run about 10 threads of it
public class MyClass implements Runnable {
private volatile Device device = null;
public MyClass(Device device) {
this.device = device;
}
#Override
public void run() {
while (true) { // <--- I do know that the "true" has to be changed to a Boolean
try {
Worker worker = new Worker();
worker.work();
System.out.println("Waiting 6 seconds!");
Thread.sleep(6 * 1000);
System.out.println("------------------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("Thread in program ended!");
}
}
and in my main I start the threads like this
for (int i = 0; i < 2; i++) {
(new Thread(new MyClass())).start();
}
This is a console based program. What is the most reliable way to end the program? I think the best way would be to change while (true) to while (Boolean) and somehow change that Boolean for all threads, then when the loop ends, the program will end gracefully.
Here i'm ending it by waiting for a user input but you can change it to fire the stop method from anywhere
public static void main(String[] args) {
List<MyClass> myThreads = new ArrayList<>();
for (int i = 0; i < 2; i++) {
MyClass myClass = new MyClass();
Thread t = new Thread(myClass);
t.start();
myThreads.add(myClass);
}
Scanner in = new Scanner(System.in);
in.next();
for(MyClass t : myThreads){
t.stop();
}
}
class MyClass implements Runnable {
private Boolean flag;
public MyClass() {
this.flag = true;
}
#Override
public void run() {
while (flag) { // <--- I do know that the "true" has to be changed to a Boolean
try {
System.out.println("Waiting 6 seconds!");
Thread.sleep(6 * 1000);
System.out.println("------------------------------------");
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("Thread in program ended!");
}
public void stop(){
this.flag = false;
} }
The easy way would be to store all your threads in a set and make loop joining them at the end.
Be aware that this is not the most ortodox neither the most efficient way to do this.
In your main:
HashSet<Thread> threads = new HashSet();
for (int i = 0; i < 2; i++) {
Thread t = new Thread(new MyClass());
threads.add(t);
t.start();
}
for (Thread thread: threads) {
thread.join();
}
some more material
The following code uses an executor service to fix the number of threads that run at any time, it provides a Future object that also tells you when your thread has shutdown gracefully. They share a shutdown object as well. This offers you a bit more flexibility as the executor service can let you decide how many threads run at any one time gracefully.
First lets created a shared shutdown object that will notify all the threads it is time to shut down. There will be one instance of this and each thread will have a copy.
public static class Shutdown {
private boolean running;
public void shutdown() {
this.running = false;
}
public boolean isRunning() {
return running;
}
}
Next let me just create a dummy thread that does nothing more than sleep forever while it is running. Obviously you can simply replace this with your own thread to do something useful.
public static class MyClass implements Runnable {
final Shutdown shutdown;
public MyClass(Shutdown shutdown) {
this.shutdown = shutdown;
}
#Override
public void run() {
while (shutdown.isRunning()) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
System.out.println("Did not gracefully shut down");
}
}
System.out.println("Thread in program ended!");
}
}
}
Now for the main class which will run everything, this is where the magic happens.
public class Main {
public static void main(String[] args) {
//run exactly 10 threads at a time
ExecutorService executorService = Executors.newFixedThreadPool(10);
//this is how we shut it down
Shutdown globalShutdown = new Shutdown();
//start up the 10 threads
List<Future<?>> futures = new ArrayList<>();
for(int i = 0; i< 10; i++)
futures.add(executorService.submit(new MyClass(globalShutdown)));
//gracefully shut them down
globalShutdown.shutdown();
try {
//wait for them all to shutdown
for(Future<?> future : futures)
future.get();
} catch (InterruptedException e) {
throw new IllegalStateException("This should never happen");
} catch (ExecutionException e) {
throw new IllegalStateException("This should never happen");
}
//everything got shutdown!
}
in practice however you probably also want to handle the case where your thread may not end gracefully due to a bug. Rather than stall forever you might want to add a timeout and if that timeout is exceeded then simply forcibly terminate all remaining threads. To do that replace the above try-catch block with this.
try {
//wait for them all to shutdown
boolean timedout = false;
for(Future<?> future : futures) {
if( !timedout ) {
try {
future.get(30, TimeUnit.SECONDS);
} catch (TimeoutException e) {
timedout = true;
}
}
if(timedout) {
future.cancel(true);
}
}
} catch (InterruptedException | ExecutionException e) {
throw new IllegalStateException("This should never happen");
}

How to avoid thread in threadpool dead when exception thrown without try catch

My code looks like this:
public class ExceptionTest {
public static Logger log = LoggerFactory.getLogger(ExceptionTest.class);
public final static ThreadFactory factory = new ThreadFactory() {
#Override
public Thread newThread(Runnable target) {
final Thread thread = new Thread(target);
log.debug("Creating new worker thread");
thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
log.error("Uncaught Exception", e);
}
});
return thread;
}
};
final static ExecutorService executor = Executors.newCachedThreadPool(factory);
public static void main(String[] args) {
executor.execute(new Runnable() {
#Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName());
int i = 1;
int j = 0;
System.out.println(i / j);
}
}
});
}
}
The console only print the message one time. This means the thread has died. Is there any other way to prevent thread death (except try catch block, this is much repeated code).
No, you can not achieve this without using try...catch block, see jls:
If no catch clause that can handle an exception can be found, then the
current thread (the thread that encountered the exception) is
terminated.
And, I do not think the termination of threads in a cached thread pool is a problem, since next time you submit a new task, a new thread will be created to handle it.
If it really matters, and you do not want repeated code, you can write a wrapper class like this:
public class WrapperRunnable implements Runnable {
Runnable runnable;
public WrapperRunnable(Runnable runnable) {
this.runnable = runnable;
}
#Override
public void run() {
while (true) {
try {
runnable.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
And submit WrapperRunnable to executor:
Runnable runnable = new Runnable() {
#Override
public void run() {
System.out.println(Thread.currentThread().getName());
int i = 1;
int j = 0;
System.out.println(i / j);
}
};
WrapperRunnable wrapperRunnable = new WrapperRunnable(runnable);
executor.execute(wrapperRunnable);

Java timeout multiple tasks in parallel

What is the best practice approach to launch a pool of 1000's of tasks (where up to 4 should be able to execute in parallel) and automatically timeout them if they take more than 3 seconds (individually)?
While I found that ExecutorService seems to be helpful (see SSCE from another post below), I don't see how to make this work for multiple tasks running in parallel (as the future.get(3, TimeUnit.SECONDS) is executing on the same thread than the one launching the tasks, hence no opportunity to launch multiple tasks in parallel):
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Test {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task());
try {
System.out.println("Started..");
System.out.println(future.get(3, TimeUnit.SECONDS));
System.out.println("Finished!");
} catch (TimeoutException e) {
future.cancel(true);
System.out.println("Terminated!");
}
executor.shutdownNow();
}
}
class Task implements Callable<String> {
#Override
public String call() throws Exception {
Thread.sleep(4000); // Just to demo a long running task of 4 seconds.
return "Ready!";
}
}
Thanks!
If you have to monitor each task to kill it when it exceeds the timeout period, either
the task itself has to keep track of time and quit appropriately, OR
you have to create a second watchdog thread for every task. The watchdog thread sets a timer and sleeps, waking up after the timeout interval expires and then terminating the task if it's still running.
This is a tricky one. Here’s what I came up with:
public class TaskQueue<T> {
private static final Logger logger =
Logger.getLogger(TaskQueue.class.getName());
private final Collection<Callable<T>> tasks;
private final int maxTasks;
private int addsPending;
private final Collection<T> results = new ArrayList<T>();
private final ScheduledExecutorService executor;
public TaskQueue() {
this(4);
}
public TaskQueue(int maxSimultaneousTasks) {
maxTasks = maxSimultaneousTasks;
tasks = new ArrayDeque<>(maxTasks);
executor = Executors.newScheduledThreadPool(maxTasks * 3);
}
private void addWhenAllowed(Callable<T> task)
throws InterruptedException,
ExecutionException {
synchronized (tasks) {
while (tasks.size() >= maxTasks) {
tasks.wait();
}
tasks.add(task);
if (--addsPending <= 0) {
tasks.notifyAll();
}
}
Future<T> future = executor.submit(task);
executor.schedule(() -> future.cancel(true), 3, TimeUnit.SECONDS);
try {
T result = future.get();
synchronized (tasks) {
results.add(result);
}
} catch (CancellationException e) {
logger.log(Level.FINE, "Canceled", e);
} finally {
synchronized (tasks) {
tasks.remove(task);
if (tasks.isEmpty()) {
tasks.notifyAll();
}
}
}
}
public void add(Callable<T> task) {
synchronized (tasks) {
addsPending++;
}
executor.submit(new Callable<Void>() {
#Override
public Void call()
throws InterruptedException,
ExecutionException {
addWhenAllowed(task);
return null;
}
});
}
public Collection<T> getAllResults()
throws InterruptedException {
synchronized (tasks) {
while (addsPending > 0 || !tasks.isEmpty()) {
tasks.wait();
}
return new ArrayList<T>(results);
}
}
public void shutdown() {
executor.shutdown();
}
}
I suspect it could be done more cleanly using Locks and Conditions instead of synchronization.

Java: Why wouldn't threads terminate

I don't understand why my threads in my simple program always fail to terminate.
I think its a easy problem but i don't see why. I think a simple exec.shutdown(); should close my Threadpool without the try and catch for exec.shutdownNow(); but dam not sure.
class 1: test ( implements a class that is running a Threadpool )
public class test {
public static void main(String[] args) throws InterruptedException{
ExecServicrunnen x = new ExecServicrunnen();
x.runningThreads();
Thread.sleep(10000);
x.getThreadtoStop();
}
}
class 2: ExecServicerunnen ( implements a Threadpool with MyTask() as Runnables )
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ExecServicrunnen {
private volatile boolean solange = true;
public void runningThreads(){
ExecutorService exec = Executors.newFixedThreadPool(5);
while(solange){
exec.execute(new myTask());
}
exec.shutdown();
try{
if(!exec.awaitTermination(60, TimeUnit.SECONDS)){
exec.shutdownNow();
}
} catch ( InterruptedException e){
e.printStackTrace();
exec.shutdownNow();
}
}
public void getThreadtoStop(){
solange = false;
}
}
class 3: myTask ( just running waiting for a while )
public class myTask implements Runnable{
public void run() {
// doSomething
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
The program always fails to terminate.
Deadlock.
x.runningThreads(); does not return before x.getThreadtoStop(); is called, but x.getThreadtoStop(); is only called after x.runningThreads(); returned. Voilà, the threads never can get stopped.
The mistake is that runningThreads() is running synchronously inside the main thread and not in its own thread. The main thread cannot send to itself the signal to terminate while waiting for the signal to terminate.
Without changing the structure of your code too much, you can solve this with another thread, like:
public class ExecServicrunnen implements Runnable {
private volatile boolean solange = true;
// Rename runningThreads() to run():
#Override
public void run() {
// The former code of runningThreads() here...
}
}
-
public class test {
public static void main(String[] args) throws InterruptedException{
ExecServicrunnen x = new ExecServicrunnen();
// Have ExecServicrunnen run in its own thread:
new Thread( x ).start();
Thread.sleep(10000);
x.getThreadtoStop();
}
}
By the way, that boolean solange logic should in most cases be realized via Thread.interrupt() and Thread.currentThread().isInterrupted() instead.

Timeout for a method

My Program looks like below
Main Program (Thread 1)
Create multiple simple java threads (Thead 1.1, 1.2...)
In each thread(1.1 or 1.2..) I'm doing some processing also calling one method which is
sometimes is not responding(CORBA calls). I want to define timer for
this method and thread(1.1 or 1.2 whoever is calling) should wait there itself till I get response or timer expired.
I have written following sample program. I don't think this is the right approach. Is there any better approach? In this prg I'm not sure when the interupt method is invoked.
public class MethodTimeout implements Runnable{
/**
* #param args
*/
public Thread t1 = null;
public int threadnum = 0;
public static void main(String[] args) {
for (int i=0; i<3; i++){
MethodTimeout mt =new MethodTimeout();
Thread t = new Thread(mt,"thread "+(i+1));
mt.t1 = t;
mt.threadnum = (i+1);
t.start();
}
System.out.println("stmt after execution");
}
public Object testTimeout(){
long startTime = System.currentTimeMillis();
try {
System.out.println("in side method start "+t1.getName()+" start time"+startTime);
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long endtime = System.currentTimeMillis();
System.out.println("in side method end "+t1.getName()+" total time"+(endtime-startTime) );
return null;
}
#Override
public void run() {
Thread timeout = new Thread (){
public void run() {
testTimeout();
};
};
timeout.start();
try {
Thread.sleep(2000);
timeout.interrupt();
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(t1.getName() + " is ending");
}
}
This very much sounds like you should implement Callable. This is just an example
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class Test {
public static void main(String[] args) throws Exception {
ExecutorService service = Executors.newFixedThreadPool(2);
Future<String> futureResult = service.submit(new MyCall());
try{
String result = futureResult.get(20, TimeUnit.MILLISECONDS);
} catch(TimeoutException timeout){
System.out.println("Timeout");
service.shutdownNow();
}
}
static class MyCall implements Callable<String> {
#Override
public String call() throws Exception {
try{
//Simulate some corba work
Thread.sleep(1000);
}catch(InterruptedException e){
Thread.currentThread().interrupt();
System.out.println("Shutting down the task!");
}
return "The result";
}
}
}
You can also make one minor change to #Eugene's answer, that is instead of calling the shutdownNow() on the ExecutorService itself you can just call cancel(true) on the futureResult that timed out. Here is the code snippet:
public class Test {
public static void main(String[] args) throws Exception {
ExecutorService service = Executors.newFixedThreadPool(2);
Future<String> futureResult = service.submit(new MyCall());
try{
String result = futureResult.get(20, TimeUnit.MILLISECONDS);
} catch(TimeoutException timeout){
System.out.println("Timeout");
} finally {
futureResult.cancel(true);
}
}
This is just to ensure that only the timed out thread is cancelled. As the shutdownNow() prevents waiting tasks from starting in addition to attempting to stop currently executing ones.

Categories

Resources