Wednesday, December 12, 2012

Handling Thread Exceptions

I've been a witness when interviewer asked candidate a question:
- "Is it any way to handle exception thrown within particular thread from client thread?"
Imagine the situation when you need to know if any exception was thrown in thread you scheduled and run. Surround Thread#start() with try-catch clause doesn't make any sense, because it's asynchronous call of Runnable.

I can suggest at least 2 ways to do it

1. Old school approach.
One can register Exception handler before starting the thread:

Thread thread = new Thread(new Runnable() {   
 public void run() {
  throw new RuntimeException("simulate failure for oldschool approach");    
  }
 });
thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() {
 public void uncaughtException(Thread t, Throwable e) {
  System.out.println("I'm in thread " + Thread.currentThread().getName());
  e.printStackTrace();
 }
});  
thread.start();

The output is following:

I'm in thread Thread-0 
java.lang.RuntimeException: simulate failure for oldschool approach 
at org.sdo.concurrency.interview.ExceptionWithinThreadTask$1.run(ExceptionWithinThreadTask.java:26) 
at java.lang.Thread.run(Thread.java:722)


UncaughtExceptionHandler#uncaughtException was executed in newly created thread. To make it visible from client thread synchronization should be used (Thread#join for instance)

2. Futures approach

System.out.println("Simulating using future");
ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
Future future = newSingleThreadExecutor.submit(new Callable
<String>() {
 public String call() throws Exception {
  throw new RuntimeException("simulate fail");
 }
 });
try {
 future.get();
}
catch (InterruptedException e) {
 e.printStackTrace();
}
catch (ExecutionException e) {
 System.out.println("I'm in thread " + Thread.currentThread().getName());
 e.printStackTrace();
}
newSingleThreadExecutor.shutdown();

The output is:

I'm in thread main
java.util.concurrent.ExecutionException: java.lang.RuntimeException: simulate fail
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:252)
at java.util.concurrent.FutureTask.get(FutureTask.java:111)
at org.sdo.concurrency.interview.ExceptionWithinThreadTask.simulateUsingFuture(ExceptionWithinThreadTask.java:52)
at org.sdo.concurrency.interview.ExceptionWithinThreadTask.main(ExceptionWithinThreadTask.java:18)
Caused by: java.lang.RuntimeException: simulate fail
at org.sdo.concurrency.interview.ExceptionWithinThreadTask$3.call(ExceptionWithinThreadTask.java:48)
at org.sdo.concurrency.interview.ExceptionWithinThreadTask$3.call(ExceptionWithinThreadTask.java:1)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)

Pay attention that exception was handled in client thread.


Conclusion

The second approach is more natural. We can surround Future#get() with try-catch clause and handle inner-thread exception from client threads. From the other side using oldschool approach leads to additional effort to make throwable visible from client thread.

Wednesday, August 29, 2012

О курении

Не то чтобы я заядлый курильщик но иногда на меня нападает сильная тяга покурить, это может продлиться от пару дней и до нескольких месяцев. Я сам себя постоянно казню за это, да и организм уже не тот, что был в студенческие годы и постоянно напоминает о вредных привычках с изрядной настойчивостью.
Бороться я с этой привычкой успешно можно с помощью спорта. Я заставлял себя бегать три раза в неделю по примерно пять километров. Когда занимаешься спортом, понимаешь как тебе плохо и как может быть хорошо если бросишь эту дрянь. В общем бегал я так пока не начал испытывать боль в правой ноге, решил приостановить забеги, нога прошла а привычка вернулась.
И вот как то я стоял на причале возле дачи на берегу лимана, смачно затягивался очередной сигаретой, и ко мне подходит старшая дочь и говорит, "папа ну зачем ты куришь, ты же можешь заболеть и умереть, а я тебя так люблю". Это было полторы недели назад, я понимаю что срок маленький, но то была последняя сигарета, с тех пор как только я  хочу за курить, я спрашиваю себя, а действительно ли я хочу умереть раньше и не увидеть как вырастут мои дочери, у меня появятся внучки/ки и правнучки/ки? Ответ приходит один - НЕТ!!!

Бросайте курить.

PS Собираюсь прикупить кроссовки для бега по твердой поверхности, посоветуйте хорошую обувь.