I have a threadfactory, executor, thread class and a runnable class.
Here is the thread class: (threadsCount is an AtomicInteger that I use to keep track of number of threads created)
public void run() {
try {
threadsCount.incrementAndGet();
super.run();
} finally {
threadsCount.decrementAndGet();
}
}
and my runnable class is currently not implemented but has empty run() method.
When I try to call Executor.execute(new RunnableClazz()), control comes to this Thread class - run() method and when it encounters super.run(), it goes to the RunnableClazz#run() method.
All these are fine. But problem is, after the RunnableClazz#run() is completed, the control doesn't come back to 'finally' block of my Thread class.
Any ideas? Do I need to manully kill the runnable at the end of run() method?
public class ThreadAA extends Thread {
private static final AtomicInteger threadsCount = new AtomicInteger();
private static final AtomicInteger threadsCreated = new AtomicInteger();
public static final String DEFAULT_NAME = "ThreadAA";
public ThreadAA(Runnable r)
{
this(r, DEFAULT_NAME);
}
public ThreadAA(Runnable r, String threadName)
{
super(r, threadName + "-" + threadsCreated.incrementAndGet());
setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler()
{
public void uncaughtException(Thread t, Throwable e)
{
logger.error("Uncaught exception in thread " + t.getName(), e);
}
});
}
#Override
public void run()
{
boolean debug = false;
//just for debug purpose
debug = true;
if(debug)
{
logger.debug("Running thread " + getName());
}
try
{
threadsCount.incrementAndGet();
super.run();
}
finally
{
threadsCount.decrementAndGet();
if(debug)
{
logger.debug("Done running thread " + getName());
}
}
}
}
My RunnableClass:
public class RunnableClazz implements Runnable {
#Override
public void run() {
logger.debug("Inside RunnableClazz");
}
}
The method that calls this runnable looks like this:
Executor executor = new Executor(25, 100, 1L, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(5), new TFactory("abc"));
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.execute(new RunnableClazz());
executor.execute(new RunnableClazz());
Please note that, I create the executor just once during server startup. I have pasted it just to give an idea on how I create it.
So executor.execute(new RunnableClazz()); creates the issue.
I copied your code and started debugging.
When you call super.run() it runs the one from ThreadPoolExecutor:
public void run() {
runWorker(this);
}
runWorker then calls RunnableClazz.run(), and after that is finished, it puts the thread on hold, waiting for new runnables to be executed. How did this happened?
In the threadFactory, which I assume it's something like this:
public Thread newThread(Runnable r) {
return new ThreadAA(r);
}
the Runnable r is not your RunnableClazz, but the ThreadPoolExecutor.
EDIT:
You may want to extend the ThreadPoolExecutor class and implement the methods:
protected void beforeExecute(Thread t, Runnable r) { }
protected void afterExecute(Runnable r, Throwable t) { }
and implement your counting there.
Related
Suppose there are multiple threads trying to find a value, whichever thread finds it first should send the output to the main thread and all other threads should be terminated.
Example -
public class WorkerThread implements Runnable {
#Override
public void run() {
// some long task here, returns int value
}
}
public class Main {
public static void main(String[] args){
// initialize multiple worker threads here
// then get result from the thread that completes first
}
}
I looked into docs and found invokeAny ExecutorService but this will return the result of any thread that has been completed successfully and not necessarily the first one.
As #Andy Turner said, use a CompletionService:
public static class WorkerThread implements Callable<Integer> {
#Override
public Integer call() throws Exception {
int nextInt = new Random().nextInt(10000);
try {
System.out.println("I will cost " + nextInt + " ms to finish job.--" + Thread.currentThread().getName());
Thread.sleep(nextInt);
} catch (InterruptedException ite) {
System.out.println("I am interrupted.--" + Thread.currentThread().getName());
return -1;
}
System.out.println("I am finish.--" + Thread.currentThread().getName());
return nextInt;
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
int nums = 3;
ExecutorService executorService = Executors.newFixedThreadPool(nums);
CompletionService<Integer> completionService = new ExecutorCompletionService<>(executorService);
while (nums-- > 0) {
completionService.submit(new WorkerThread());
}
Integer firstValue = completionService.take().get();
System.out.println("FirstValue is " + firstValue);
executorService.shutdownNow();
}
And you can see in output, only one thread will complete the job (Because only call completionService#take once
), other threads will be interrupted and exit
:
I will cost 8943 ms to finish job.--pool-1-thread-1
I will cost 9020 ms to finish job.--pool-1-thread-2
I will cost 5025 ms to finish job.--pool-1-thread-3
I am finish.--pool-1-thread-3
FirstValue is 5025
I am interrupted.--pool-1-thread-1
I am interrupted.--pool-1-thread-2
You can also use CountDownLatch and ExecutorService for achieving this.
Create CountDownLatch object with count = 1.
CountDownLatch latch = new CountDownLatch(1);
Use ExecutorService pool to execute the threads and pass the latch in all the threads.
workerThreadPool.execute(new WorkerThread(latch));
Wait for any thread to complete it's operation.
latch.await();
In the finally block of the thread run, shutdown the latch.
latch.countDown();
As soon as any thread countDown's the latch, the threadpool will stop all the other threads and shutdown.
workerThreadPool.shutdownNow();
The complete example would be below.
import static java.lang.Thread.sleep;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class WorkerThread implements Runnable
{
CountDownLatch _latch;
public WorkerThread(CountDownLatch latch)
{
_latch = latch;
}
#Override
public void run()
{
try
{
// some long task here, returns int value
System.out.println("In thread1 " + this.toString());
sleep(5000);
}
catch (InterruptedException ex)
{
System.out.println("thread1 interupted");
}
finally
{
System.out.println("Finished1 " + this.toString());
_latch.countDown();
}
}
}
class WorkerThread2 implements Runnable
{
CountDownLatch _latch;
public WorkerThread2(CountDownLatch latch)
{
_latch = latch;
}
#Override
public void run()
{
try
{
// some long task here, returns int value
System.out.println("In thread2 " + this.toString());
sleep(10000);
}
catch (InterruptedException ex)
{
System.out.println("thread2 interupted");
}
finally
{
System.out.println("Finished2 " + this.toString());
_latch.countDown();
}
}
}
public class Main
{
public static void main(String[] args) throws InterruptedException
{
ExecutorService workerThreadPool = Executors.newFixedThreadPool(2);
CountDownLatch latch = new CountDownLatch(1);
workerThreadPool.execute(new WorkerThread(latch));
workerThreadPool.execute(new WorkerThread2(latch));
latch.await();
workerThreadPool.shutdownNow();
}
}
You -could- pass a reference to the Thread where the Thread can send its results. But you'd better follow advice in the other answers and use a better API for this :)
public static void main(//) {
ResultConsumer r = new ResultConsumer();
... create and start worker threads
}
public class WorkerThread implements Runnable {
public WorkerThread ( ResultConsumer r ) {
this.r=r
}
#Override
public void run() {
// some long task here, returns int value
r.sendResult(....)
}
}
I create a Callable which should make a syncExec call. I delegate the Callable to a subclass of RecursiveTask (ForkJoinPool) which executes the call method of the Callable. The problem is that the code inside the run method is never reached. Do you know why and how to fix that?
public class someClass{
public static void main (String[] args){
Callable<Object> c = new Callable<Object>() {
#Override
public Object call() throws Exception {
PlatformUI.getWorkbench().getDisplay().syncExec(new Runnable() {
#Override
public void run() {
System.out.println("hi");
}
});
return null;
}
});
ATLockTask task = new ATLockTask();
task.setCallable(c);
ForkJoinPool pool = new ForkJoinPool();
pool.invoke(task);
}
}
public class ATLockTask extends RecursiveTask<Object[]>{
Callable callable;
#Override
protected Object[] compute() {
try {
callable.call();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
ForkJoinPool.invoke blocks the current thread until the given task has completed. Display.syncExec waits until the SWT UI thread executes Display.readAndDispatch so it will wait forever because ForkJoinPool.invoke is blocking the UI thread.
Use ForkJoinPool.execute to start the task without blocking and the code works.
I have been wanting for a long time to add schedulers to my API. So I set a class for the purpose. Here it is.
public abstract class SyncScheduler extends Scheduler {
private Thread thread = null;
private boolean repeating = false;
#Override
public synchronized void runTask() {
thread = new Thread(this);
thread.start();
}
#Override
public synchronized void runTaskLater(long delay) {
thread = new Thread(this);
try {
Thread.sleep(delay * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
thread.run();
}
#Override
public synchronized void runRepeatingTask(long period) {
thread = new Thread(this);
repeating = true;
while (!thread.isInterrupted()) {
thread.run();
try {
Thread.sleep(period * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public synchronized void cancel() {
if (thread != null || !repeating) {
throw new SchedulerException("Scheduler is not started or is not a repeating task!");
} else {
thread.interrupt();
repeating = false;
}
}}
Scheduler just implements Runnable.
The problem is that whenever I try to create 2 or more Schedulers, the second one never starts until the first one is finished! For example if I have on Scheduler that runs every X seconds and I have another one the cancels it, the one that cancels the first one never starts! This is the problem.
How could I run two of these schedulers in parallel?
Also these are my two test main classes.
public class Test {
static Scheduler scheduler = new SyncScheduler() {
#Override
public void run() {
System.out.println("It works.");
}
};
public static void main(String[] args) {
scheduler.runRepeatingTask(1);
new SyncScheduler() {
#Override
public void run() {
System.out.println("Stopped.");
scheduler.cancel();
}
}.runTaskLater(2);
}}
And here's the second one.
public class Test {
static Scheduler scheduler = new SyncScheduler() {
#Override
public void run() {
System.out.println("It works.");
new SyncScheduler() {
#Override
public void run() {
System.out.println("Stopped.");
scheduler.cancel();
}
}.runTaskLater(2);
}
};
public static void main(String[] args) {
scheduler.runRepeatingTask(1);
}}
The first one outputs "It works." repeatedly until I force stop the test.
The second one gives me "It works." for once, then It gives me "Stopped." and with it and exception.
You are using the thread object wrongly.
To start a Runnable object (in this case, Thread object) in a different thread, the object must call start() method. You are using run() method, which just calling the method in the same thread without creating a new thread.
Try to change run() in SyncScheduler.runRepeatingTask and SyncScheduler.runTaskLater.
Also, I just noticed in your cancel() method:
if (thread != null || !repeating) {
throw new SchedulerException("Scheduler is not started or is not a repeating task!");
} else {
thread.interrupt();
repeating = false;
}
This would make the method throw exception if thread started. I think it should be if (thread == null || !repeating) {
So, i apologize for the title. It's quite hard to explain in one sentence what i would like to do if you have no idea on how it is called.
So assume i can only use primitive thread functions (wait, notify, no concurrent package)
The program has 3 threads, all of them are the same and are called by the main thread. They behave normally until one of the three get an exception and so it must wait for the end of the remaining 2 threads in order to start a recovery process.
I was thinking about a static variable but I'm not really sure about it, i would love to keep it as simple as possible.
Each thread starts at the same time.
I don't see any reason why you can't use a static variable like you suggest. Here's how I would do it with an inner class...
private static boolean running = true;
public void test26546397() {
while (true) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread(new MyRunnable());
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
running = true;
// Do recovery
}
}
public class MyRunnable implements Runnable {
#Override
public void run() {
while (running) {
try {
// doStuff
} catch (Exception ex) {
running = false;
}
}
}
}
I would of course replace the while (true) with something a little more suitable.
I think you need java.concurrent.CountdownLatch, however if the java.concurrent package is not available to you can code this yourself using Object.wait/notify and synchronized blocks.
The latch can then be decremented in a finally {} on each Thread, this will be run if the Thread completes, or an exception occurs.
Your main program then just needs to wait for count to become 0.
public class StackOverflow26546397 {
static class CountdownLatch {
private int count;
private Object monitor = new Object();
public CountdownLatch(int count) {
this.count = count;
}
public void countDown() {
synchronized (monitor) {
count--;
monitor.notifyAll();
}
}
public void await() throws InterruptedException {
synchronized (monitor) {
while (count > 0) {
monitor.wait();
}
}
}
}
static class Job implements Runnable {
private CountdownLatch latch;
public Job(CountdownLatch latch) {
this.latch = latch;
}
#Override
public void run() {
try {
// do work.
Thread.sleep((long) (Math.random() * 3000d));
} catch (InterruptedException e) {
//
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) throws InterruptedException {
CountdownLatch latch = new CountdownLatch(3);
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
latch.await();
System.out.println("All threads finished");
}
}
Not sure what you are trying to do but this is as simple as I can think of (just native concurrency):
Create a static or shared volatile boolean
private static volatile boolean exceptionOccured=false
Set the above to 'true' when exception occurs:
....}catch(Exception e){
exceptionOccured=true;
}
Check this periodically in you normal thread flow:
if (exceptionOccured)
//enter you synchronized call here
the synchronized method could look something like:
public synchronized void checkAndRecover(){
//decrement a counter or other logic to identify which is the last Thread and then
//perform any recovery logic
}
I have a thread inside a class like this-
import java.util.Observable;
public class Download extends Observable {
private int state = 0;
private final Thread myThread = new Thread(() -> {
/*
some work to do here
*/
setChanged();
notifyObservers(state);
});
public void download(int state) {
if (!myThread.isAlive()) {
this.state = state;
myThread.start();
}
}
public Thread getThread() {
return myThread;
}
public static void MyMethod() throws InterruptedException {
Download down = new Download();
down.addObserver((Observable ob, Object dat) -> {
System.out.println(ob);
if ((int) dat == 1) {
down.download(2);
} else {
System.out.println("success");
}
});
down.download(1);
down.getThread().join();
}
public static void main() throws InterruptedException {
MyMethod();
}
}
The problem is I never get it to print the "success" message.
I assume, it is because all observers are being notified from inside of MyThread. So when down.download(2) is called from the observer inside MyMethod(), the previous thread is still running and the call is ignored.
How can I notify all observers from the main thread, not from the myThread?
You are calling down.download(2) from within the execution of MyThread, therefore the thread is still alive which means that your download method does nothing because of if(!myThread.isAlive()).
I would recommend you to use the Executor framework and Listenable Futures from Guava instead of creating threads manually. Example code from the Guava wiki:
ListeningExecutorService service =
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<Explosion> explosion = service.submit(new Callable<Explosion>() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback<Explosion>() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
Note that Futures.addCallback(..) also has an overload which allows you to determine which executor should execute the callback, this seems to be what you want.