Is it possible to attach an UncaughtExceptionHandler to a TimerTask?
(Other than by calling Thread.setDefaultUncaughtExceptionHandler())
You can write a TimerTask proxy that catches Throwable from run.
public final class TimerTaskCatcher extends TimerTask {
private final TimerTask orig;
private final Thread.UncaughtExceptionHandler handler;
public TimerTaskCatcher(
TimerTask orig,
Thread.UncaughtExceptionHandler handler
) {
if (orig == null || handler == null) {
throw new NullPointerException();
}
this.orig = orig;
this.handler = handler;
}
#Override public boolean cancel() {
// **Edit:** Correction report due to #Discape.
// In fact, this entire method could be elided.
boolean weirdResult;
try {
orig.cancel();
} finally {
weirdResult = super.cancel();
}
return weirdResult;
}
#Override public void run() {
try {
orig.run();
} catch (Throwable exc) {
handler.uncaughtException(Thread.currentThread(), exc);
}
}
#Override public long scheduledExecutionTime() {
return orig.scheduledExecutionTime();
}
}
BTW: You might want to consider using java.util.concurrent instead of Timer.
Yes, I think so. There's an instance method (setUncaughtExceptionHandler) in Thread class that set's the thread's UncaughtExceptionHandler.
In your run method of the TimerTask you can do something like this:
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(eh);
}
Related
I would like to pause the new tasks from executing. The example provided in the Official Documentation seems to be stopping the currently executed tasks as well (though I am wondering how it does that without interrupting the thread).
class PausableThreadPoolExecutor extends ThreadPoolExecutor {
private boolean isPaused;
private ReentrantLock pauseLock = new ReentrantLock();
private Condition unpaused = pauseLock.newCondition();
public PausableThreadPoolExecutor(...) { super(...); }
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
pauseLock.lock();
try {
while (isPaused) unpaused.await();
} catch (InterruptedException ie) {
t.interrupt();
} finally {
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused = true;
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused = false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
}
Wrapping the Runnable interface could be easier for this, then you don't have to make your own ThreadPool.
public abstract class PausableRunnable implements Runnable{
private final object _monitor;
public PausableRunnable(object monitor){
_monitor = monitor;
}
#Override
public void Run(){
WaitForNotify();
}
public void WaitForNotify(){
synchronized(_monitor){
while(!done){
_monitor.wait();
}
}
doWork();
}
public abstract void doWork();
}
This could pause new threads easily. Pausing a running thread is a different task, I think this is what you meant. The biggest problem with my solution is if you already want to inherit from something, but it's a starting point
The question was incorrect. The PausablableThreadPoolExecutor does not stop the currently executed thread. Apologies for the incorrect question.
EDIT:
Edited the question in response to #maress answer below.
I have a web service in java (async enabled), which when called performs a call to another service asynchronously. In my Controller I have this:
private boolean receivedEvent = false;
private final Object SYNC = new Object();
public Callable<String> doStuff()
{
callSomeAsyncFunction();
return new Callable<String> ()
{
#Override
public String call() throws Exception {
synchronized (SYNC)
{
while (receivedEvent == false)
{
SYNC.wait();
}
receivedEvent = false;
System.out.println("RETURN");
return "ok";
}
}
};
}
public void onMyEvent(MyEvent event)
{
synchronized (SYNC)
{
receivedEvent = true;
System.out.println("RECEIVED");
SYNC.notify();
}
}
EDIT: The notification never gets through. System.out.println("RETURN") is never called. The events are being received ('RECEIVED' is shown).
Now all I want to do is wait for the callSomeAsyncFunction() to finish executing. When done, it triggers an event on the handler public void onMyEvent(MyEvent event).
Any suggestions? I am not even sure if my approach makes sense at all.
Synchronize always on a final instance.
private MyEvent myEvent;
private final Object SYNC = new Object();
public Callable<String> doStuff()
{
callSomeAsyncFunction();
return new Callable<String> ()
{
#Override
public String call() throws Exception {
synchronized (SYNC)
{
while (myEvent == null)
{
SYNC.wait();
}
return "ok";
}
}
};
}
public void onMyEvent(MyEvent event)
{
synchronized (SYNC)
{
myEvent = event;
SYNC.notifyAll();
}
}
Note: I'm new to english, so please forgive me for any wrong in it.
I use thread-local for save a resource per-thread; and use it(thread-local) in a some tasks. I run my task by a java executor-service. I would close my resources when a thread going to terminate; then i need run a task in all created threads by executor-service, after me call "executor.shoutdown" method. how i can force executor to run a task per-thread, when it would terminate those?
import java.util.concurrent.*;
public class Main2 {
public static void main(String[] args) {
ExecutorService executor = new ForkJoinPool(3);
SimpleValue val = new SimpleValue();
for(int i=0; i<1000; i++){
executor.execute(new Task(val));
}
executor.shutdown();
while( true ) {
try {
if( executor.awaitTermination(1, TimeUnit.SECONDS) ) System.exit(0);
} catch(InterruptedException intrExc) {
// continue...
}
}
}
protected static interface ResourceProvider<T>
extends AutoCloseable {
public T get();
public ResourceProvider<T> reset() throws Exception;
public ResourceProvider<T> reset(boolean force) throws Exception;
public void close();
}
protected static abstract class ThreadLocalResourceProvider<T>
extends ThreadLocal<T>
implements ResourceProvider<T> {}
protected static class SimpleValue
extends ThreadLocalResourceProvider<String> {
public String initialValue() {
return "Hello " + Thread.currentThread().getName();
}
public SimpleValue reset() throws Exception {
return reset(false);
}
public SimpleValue reset(boolean force) throws Exception{
set(this.initialValue());
return this;
}
public void close() {
remove();
}
}
protected static class Task
implements Runnable {
protected SimpleValue val;
public Task(SimpleValue val) {
this.val = val;
}
#Override
public void run() {
try {
System.out.print(val.reset().get());
} catch( Exception exc ) {
System.out.print( exc.getMessage() );
}
}
}
}
Most executors can be constructed with a ThreadFactory. That's also true for ForkJoinPool. However, for simplification, I use a different ExecutorService.
ExecutorService executor = Executors.newFixedThreadPool(
10, new FinalizerThreadFactory(Executors.defaultThreadFactory()));
The class FinalizerThreadFactory delegates the creation of threads to the passed thread factory. However, it creates threads that will execution some additional code before they exit. That's quite simple:
class FinalizerThreadFactory implements ThreadFactory {
private final ThreadFactory delegate;
public FinalizerThreadFactory(ThreadFactory delegate) {
this.delegate = delegate;
}
public Thread newThread(final Runnable r) {
return delegate.newThread(new Runnable() {
public void run() {
try {
r.run();
} finally {
// finalizer code goes here.
}
}
});
}
}
I just noticed the following phenomena when cancelling a Future returned by ForkJoinPool. Given the following example code:
ForkJoinPool pool = new ForkJoinPool();
Future<?> fut = pool.submit(new Callable<Void>() {
#Override
public Void call() throws Exception {
while (true) {
if (Thread.currentThread().isInterrupted()) { // <-- never true
System.out.println("interrupted");
throw new InterruptedException();
}
}
}
});
Thread.sleep(1000);
System.out.println("cancel");
fut.cancel(true);
The program never prints interrupted. The docs of ForkJoinTask#cancel(boolean) say:
mayInterruptIfRunning - this value has no effect in the default implementation because interrupts are not used to control cancellation.
If ForkJoinTasks ignore interrupts, how else are you supposed to check for cancellation inside Callables submitted to a ForkJoinPool?
This happens because Future<?> is a ForkJoinTask.AdaptedCallable which extends ForkJoinTask, whose cancel method is:
public boolean cancel(boolean mayInterruptIfRunning) {
return setCompletion(CANCELLED) == CANCELLED;
}
private int setCompletion(int completion) {
for (int s;;) {
if ((s = status) < 0)
return s;
if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) {
if (s != 0)
synchronized (this) { notifyAll(); }
return completion;
}
}
}
It does not do any interruptions, it just sets status. I suppose this happens becouse ForkJoinPools's Futures might have a very complicated tree structure, and it is unclear in which order to cancel them.
Sharing some more light on top of #Mkhail answer:
Using ForkJoinPool execute() instead of submit() will force a failed Runnable to throw a worker exception, and this exception will be caught by the Thread UncaughtExceptionHandler.
Taking from Java 8 code:
submit is using AdaptedRunnableAction().
execute is using RunnableExecuteAction() (see the rethrow(ex)).
/**
* Adaptor for Runnables without results
*/
static final class AdaptedRunnableAction extends ForkJoinTask<Void>
implements RunnableFuture<Void> {
final Runnable runnable;
AdaptedRunnableAction(Runnable runnable) {
if (runnable == null) throw new NullPointerException();
this.runnable = runnable;
}
public final Void getRawResult() { return null; }
public final void setRawResult(Void v) { }
public final boolean exec() { runnable.run(); return true; }
public final void run() { invoke(); }
private static final long serialVersionUID = 5232453952276885070L;
}
/**
* Adaptor for Runnables in which failure forces worker exception
*/
static final class RunnableExecuteAction extends ForkJoinTask<Void> {
final Runnable runnable;
RunnableExecuteAction(Runnable runnable) {
if (runnable == null) throw new NullPointerException();
this.runnable = runnable;
}
public final Void getRawResult() { return null; }
public final void setRawResult(Void v) { }
public final boolean exec() { runnable.run(); return true; }
void internalPropagateException(Throwable ex) {
rethrow(ex); // rethrow outside exec() catches.
}
private static final long serialVersionUID = 5232453952276885070L;
}
I have multiple consumer threads waiting on a CountDownLatch of size 1 using await(). I have a single producer thread that calls countDown() when it successfully finishes.
This works great when there are no errors.
However, if the producer detects an error, I would like for it to be able to signal the error to the consumer threads. Ideally I could have the producer call something like abortCountDown() and have all of the consumers receive an InterruptedException or some other exception. I don't want to call countDown(), because this requires all of my consumer threads to then do an additional manual check for success after their call to await(). I'd rather they just receive an exception, which they already know how to handle.
I know that an abort facility is not available in CountDownLatch. Is there another synchronization primitive that I can easily adapt to effectively create a CountDownLatch that supports aborting the countdown?
JB Nizet had a great answer. I took his and polished it a little bit. The result is a subclass of CountDownLatch called AbortableCountDownLatch, which adds an "abort()" method to the class that will cause all threads waiting on the latch to receive an AbortException (a subclass of InterruptedException).
Also, unlike JB's class, the AbortableCountDownLatch will abort all blocking threads immediately on an abort, rather than waiting for the countdown to reach zero (for situations where you use a count>1).
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class AbortableCountDownLatch extends CountDownLatch {
protected boolean aborted = false;
public AbortableCountDownLatch(int count) {
super(count);
}
/**
* Unblocks all threads waiting on this latch and cause them to receive an
* AbortedException. If the latch has already counted all the way down,
* this method does nothing.
*/
public void abort() {
if( getCount()==0 )
return;
this.aborted = true;
while(getCount()>0)
countDown();
}
#Override
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
final boolean rtrn = super.await(timeout,unit);
if (aborted)
throw new AbortedException();
return rtrn;
}
#Override
public void await() throws InterruptedException {
super.await();
if (aborted)
throw new AbortedException();
}
public static class AbortedException extends InterruptedException {
public AbortedException() {
}
public AbortedException(String detailMessage) {
super(detailMessage);
}
}
}
Encapsulate this behavior inside a specific, higher-level class, using the CountDownLatch internally:
public class MyLatch {
private CountDownLatch latch;
private boolean aborted;
...
// called by consumers
public void await() throws AbortedException {
latch.await();
if (aborted) {
throw new AbortedException();
}
}
// called by producer
public void abort() {
this.aborted = true;
latch.countDown();
}
// called by producer
public void succeed() {
latch.countDown();
}
}
You can create a wrapper around CountDownLatch that provides the ability to cancel the waiters. It will need to track the waiting threads and release them when they timeout as well as remember that the latch was cancelled so future calls to await will interrupt immediately.
public class CancellableCountDownLatch
{
final CountDownLatch latch;
final List<Thread> waiters;
boolean cancelled = false;
public CancellableCountDownLatch(int count) {
latch = new CountDownLatch(count);
waiters = new ArrayList<Thread>();
}
public void await() throws InterruptedException {
try {
addWaiter();
latch.await();
}
finally {
removeWaiter();
}
}
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
try {
addWaiter();
return latch.await(timeout, unit);
}
finally {
removeWaiter();
}
}
private synchronized void addWaiter() throws InterruptedException {
if (cancelled) {
Thread.currentThread().interrupt();
throw new InterruptedException("Latch has already been cancelled");
}
waiters.add(Thread.currentThread());
}
private synchronized void removeWaiter() {
waiters.remove(Thread.currentThread());
}
public void countDown() {
latch.countDown();
}
public synchronized void cancel() {
if (!cancelled) {
cancelled = true;
for (Thread waiter : waiters) {
waiter.interrupt();
}
waiters.clear();
}
}
public long getCount() {
return latch.getCount();
}
#Override
public String toString() {
return latch.toString();
}
}
You could roll your own CountDownLatch out using a ReentrantLock that allows access to its protected getWaitingThreads method.
Example:
public class FailableCountDownLatch {
private static class ConditionReentrantLock extends ReentrantLock {
private static final long serialVersionUID = 2974195457854549498L;
#Override
public Collection<Thread> getWaitingThreads(Condition c) {
return super.getWaitingThreads(c);
}
}
private final ConditionReentrantLock lock = new ConditionReentrantLock();
private final Condition countIsZero = lock.newCondition();
private long count;
public FailableCountDownLatch(long count) {
this.count = count;
}
public void await() throws InterruptedException {
lock.lock();
try {
if (getCount() > 0) {
countIsZero.await();
}
} finally {
lock.unlock();
}
}
public boolean await(long time, TimeUnit unit) throws InterruptedException {
lock.lock();
try {
if (getCount() > 0) {
return countIsZero.await(time, unit);
}
} finally {
lock.unlock();
}
return true;
}
public long getCount() {
lock.lock();
try {
return count;
} finally {
lock.unlock();
}
}
public void countDown() {
lock.lock();
try {
if (count > 0) {
count--;
if (count == 0) {
countIsZero.signalAll();
}
}
} finally {
lock.unlock();
}
}
public void abortCountDown() {
lock.lock();
try {
for (Thread t : lock.getWaitingThreads(countIsZero)) {
t.interrupt();
}
} finally {
lock.unlock();
}
}
}
You may want to change this class to throw an InterruptedException on new calls to await after it has been cancelled. You could even have this class extend CountDownLatch if you needed that functionality.
Since Java 8 you can use CompletableFuture for this. One or more threads can call the blocking get() method:
CompletableFuture<Void> cf = new CompletableFuture<>();
try {
cf.get();
} catch (ExecutionException e) {
//act on error
}
another thread can either complete it successfully with cf.complete(null) or exceptionally with cf.completeExceptionally(new MyException())
There is a simple option here that wraps the CountDownLatch. It's similar to the second answer but does not have to call countdown repeatedly, which could be very expensive if the latch is for a large number. It uses an AtomicInteger for the real count, with a CountDownLatch of 1.
https://github.com/scottf/CancellableCountDownLatch/blob/main/CancellableCountDownLatch.java
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
public class CancellableCountDownLatch {
private final AtomicInteger count;
private final CountDownLatch cdl;
public CancellableCountDownLatch(int count) {
this.count = new AtomicInteger(count);
cdl = new CountDownLatch(1);
}
public void cancel() {
count.set(0);
cdl.countDown();
}
public void await() throws InterruptedException {
cdl.await();
}
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
return cdl.await(timeout, unit);
}
public void countDown() {
if (count.decrementAndGet() <= 0) {
cdl.countDown();
}
}
public long getCount() {
return Math.max(count.get(), 0);
}
#Override
public String toString() {
return super.toString() + "[Count = " + getCount() + "]";
}
}