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: 可以拿到任务返回结果