The java.lang.Thread class is the core of the low level multi-threading in Java. Almost every java developer know start a new thread is very simple. first, create a instance from Thread or subclass of Thread, then call start() method of that instance. WALA, the new thread is in runnable state and ready to run.
In a nontrivial project, very possibly there are some other methods need to be invoked after you create the thread instance and before start() get called. Let's take a look at these candidates in a hello world level demo.
package com.shengwang.demo;
class MyDummyTask implements Runnable {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.printf("Start working in %s\n", threadName);
throw new RuntimeException("some thing wrong");
}
}
public class MyThread {
public static void main(String[] args) throws InterruptedException {
MyDummyTask r = new MyDummyTask();
Thread t = new Thread(r);
//-----------------------------
// opt 1. set thread name
//-----------------------------
t.setName("helloThread");
//-----------------------------
// opt 2. set Exception handler
//-----------------------------
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(formatException(t, e));
}
private String formatException(Thread t, Throwable e) {
StackTraceElement[] ste = e.getStackTrace();
String exceptionRootLocation = ste.length > 0 ? ste[0].toString() : "Root cause not specified";
StringBuilder sb = new StringBuilder();
sb.append("Thread Exception [");
sb.append(t.getName());
sb.append("]: ");
sb.append(e.toString());
sb.append(" at <");
sb.append(exceptionRootLocation);
sb.append(">");
return sb.toString();
}
});
//-----------------------------
// opt 3. set daemon
//-----------------------------
t.setDaemon(true);
t.start();
t.join();
}
}
1. Set thread's name
This is the most possible thing you may want to do before start the new thread by calling setName(). The default thread name will be 'Thread-n' if create by hand or 'pool-x-thread-y' if created by default ThreadFactory of Execuors. It will be very much helpful to set it a meaningful name.
2. Set the exception handler
In production, it's not rare to see a thead in multi-thread application raises exception. This exception need to be handled or logged to make the application get improved. The developer should set a customized handler to make this done using setUncaughtExceptionHandler()
In Java when uncaught Exception happens in thread, the order to handle the exception is thead's uncaughtExceptionHandler (like we set in the demo above)-> thread group's uncaughtException() method -> default uncaught exception handler. You can choose which layer you want to cut in.
3. Set Daemon
This is much more optional. It depends on your application. JVM will wait for any non-daemon thread to finish before application can finish. So if sub threads' interruption is not your concern, You an set them to daemon so you can quite the application fast.
4. More
In real project, the concurrency is based more on java.util.concurrent.ExecutorService instead of using creating Thread directly. So a customized ThreadFactory will always be used to set the properties on the thread instances before thread instances get involved in any kind of thread pools.
0 comments:
Post a Comment