一。java创建线程的两种方式。
java创建线程有两种方式:1.继承Thread类,重写run()。2.实现Runnable接口,重写run()。下面分别看代码:
public class MyThread extends Thread {
@Override
public void run() {
System.out.println("Hello Thread!");
}
}
实现Runnable接口:
public class MyThread implements Runnable {
@Override
public void run() {
System.out.println("Hello Thread!");
}
}
接下来,跑一下试试:
public static void main(String[] args) {
Thread t = new MyThread();
t.start();
//t.run(); //请不要这样,这样还是一个线程。要启动一个线程,调用start()方法。至于原因,请看jdk的源码
}
二。jdk5提供的线程池
从jdk5开始,提供了java.util.concurrent包,提供了几个线程池。下面看用法:
ExecuteService exec = Executors.newCachedThreadPool();//产生线程数,与所需的数量一致。
exec.execute(new MyThread()); //自己定义的Runnable对象
exec.shutdown(); //必须关闭已回收资源
除了CachedThreadPool外,jdk还提供了SingleThreadExecutor,用于产生单一线程,如果您有多个任务,使用此线程池时,这些任务将排队。
还有FixedThreadPool,产生固定数量的线程。
如果您要从任务(线程)中产生返回值,怎么办? Runnable的run()方法是没有返回值的,怎么做呢?
jdk5提供了Callable接口,和Future类,我们看看用法:
public class ThreadWithResult implements Callable<String> {
@override
public String call() {
return "hi, result!";
}
public static void main(String[] args) {
ExecuteService exec = Executors.newCachedThreadPool();
Future future = exec.submit(new ThreadWithResult()); //不在使用execute(),使用submit(),返回future对象
System.out.println(future.get());
}
}
三。异常捕获
话不多说,直接上代码:
class MyThread implements Runnable {
public void run() {
//...
throw new RunntimeException();
}
public static void main(String[] args) {
Thread t = new Thread(new MyThread());
t.setUncaughtExceptionHandler(new MyThreadExceptionHandler()); //设置异常捕获器
t.start();
}
}
//异常捕获器类
class MyThreadExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t.getName());
e.printStackTrance();
}
}