Java中有三种线程创建方式
1.继承Thread类,重写run方法
2.实现Runnable接口,实现run方法
3.使用FutureTask方式,即Callable的call方法
继承Thread类
public class ThreadTest {
public static class MyThread extends Thread {
@Override
public void run() {
System.out.println("我是子线程");
}
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
此方式的好处: 在run方法内获取当前线程直接使用this即可,无需使用Thread.currentThread方法
此方式的坏处: 无法再继承其他类
任务没有返回值
任务与代码没有分离,当多个线程执行同样的任务时,同样需要多份代码,而Runnable没有这个限制
实现Runnable
public class ThreadTest {
public static class RunnableTest implements Runnable {
@Override
public void run() {
System.out.println("我是子线程");
}
}
public static void main(String[] args) {
RunnableTest test = new RunnableTest();
new Thread(test).start();
new Thread(test).start();
}
}
如果有必要,可以添加参数进行任务区分
优点: 可以继承其他类
缺点: 任务没有返回值
FutureTask
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class ThreadTest {
public static class CallTest implements Callable<String> {
@Override
public String call() throws Exception {
return "hello world";
}
}
public static void main(String[] args) throws InterruptedException {
//创建异步任务
FutureTask<String> futureTask = new FutureTask<>(new CallTest());
new Thread(futureTask).start();
try {
//等待线程执行结束,拿到返回结果
String result = futureTask.get();
System.out.println(result);
}catch (ExecutionException e) {
e.printStackTrace();
}
}
}
此方式可以拿到任务的返回结果
小结
使用继承:方便传参,可以在子类里添加成员变量,通过setter或者构造函数传参;但不能继承其他类;无法拿到任务结果
使用Runnale:只能使用主线程里被声明为final的变量;无法拿到任务结果
使用FutureTask: 可以拿到任务返回结果