一般来说,创建线程有三种方式:继承 Thread 类、实现 Runnable 接口和实现 Callable 接口。
继承 Thread 类:继承 Thread 类,重写 run() 方法,调用 start() 方法启动线程。
public class MyThread {
public static class MyThreadTest1 extends Thread {
@Override
public void run() {
System.out.println("继承 Thread 类");
}
}
public static void main(String[] args) {
MyThreadTest1 myThreadTest1 = new MyThreadTest1();
myThreadTest1.start();
}
}
实现 Runnable 接口:实现 Runable 接口,重写 run() 方法。
public class Mythread2 implements Runnable {
@Override
public void run() {
System.out.println("实现 Runnable 接口");
}
public static void main(String[] args) {
Mythread2 mythread2 = new Mythread2();
new Thread(mythread2).start();
}
}
可以看到以上两种方式都是在调用 start() 方法时调用了 run() 方法,那为什么不能直接去调用 run() 方法呢?其实以上这两种方式如果直接调用 run() 方法的时候也是能成功执行的。
JVM 在执行 start() 方法时,会先创建一个新线程,由创建出来的新线程去执行 Thread 的 run() 方法,这才起到多线程的效果。如果直接调用 Thread 的 run() 方法,那么 run() 方法还是运行在主线程中,相当于顺序执行,就起不到多线程的效果。
以上这两种创建线程的方法都是没有返回值的,如果我们需要关注线程执行结果的话,就需要第三种创建线程的方式。
实现 Callable 接口:实现 Callable 接口,重写 call() 方法,这种方式可以通过 FutureTask 获取任务执行的返回值。
public class MyThread3 implements Callable {
@Override
public Object call() throws Exception {
return "实现 Callable 接口";
}
public static void main(String[] args) {
//创建异步任务
FutureTask<String> task=new FutureTask<String>(new MyThread3());
//启动线程
new Thread(task).start();
try {
//等待执行完成,并获取返回结果
String result = task.get();
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}