方法一:直接使用 Thread
// 创建线程对象
Thread t = new Thread(){
@Override
public void run() {
// 要执行的任务
log.debug("running");
}
};
// 给线程指定名字
t.setName("t1");
// 启动线程
t.start();
方法二:使用 Runnale 接口配合 Thread
// 创建任务对象
Runnable task2 = new Runnable() {
@Override
public void run() {
log.debug("hello");
}
};
// 参数1 是任务对象;
// 参数2 是线程名字,推荐
Thread t2 = new Thread(task2, "t2");
t2.start();
方法三:FutureTask 配合 Thread
// 创建任务对象
FutureTask<Integer> task = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
log.debug("running.....");
Thread.sleep(1000);
return 100;
}
});
// 参数1是任务对象;
// 参数2是线程名字,推荐
Thread t = new Thread(task, "t1");
t.start();
log.debug("结果是 {}", task.get());
总结
从Thread的 run方法源码来看,方法一是直接重写了 run方法,方法二是调用 Runnable 接口的 run 方法。即Thread run 方法的内部逻辑是先判断 Runable 接口是否为空,不为空就调用接口的 run 方法,否则就默认使用 Thread 的方法。方法二实现了把线程和任务分离,有很好的复用性。方法三的 FutureTask<V> 类实现了 RunnableFuture<V> 接口,而 RunnableFuture<V>接口继承了 Runnable, Future<V> 两个接口,因此可以借助 FutureTask<V> 来创建线程。