创建线程的几种方式
1.new一个thread类的对象形式创

2.Runnable接口配合thread类创建

3.通过FutureTask配合Thread类创建(会有返回值的线程)

原理讲解
方式一(new一个thread类的对象形式创线程)

Thread thread =new Thread();这种方式就是调用Thread类中的构造方法,然后执行init()方法,最后实际就是重写Thread类中的run()方法,当run()方法被重写后,子类对象会执行自己的run()方法。
方式二(Runnable接口配合thread类创建)

Thread thread1 =new Thread(runnable);这其实是Thread类的带参构造方法,参数类型是Runnable接口类型,该构造方法也是先执行init方法,最后回归Thread类中的run()方法,只是此时target参数不是空,而是我们定义的runnable参数,这个时候run方法会直接执行runnable对象中的run()方法。

结论:
其实创建线程的第一种方法和第二种方法其实本质都是调用到Thread类中的run()方法,只是两种不同的情况,Thread thread =new Thread();是重写Thread类的run()方法。而Thread thread1 =new Thread(runnable);是直接调用runnable对象里面的run()方法。
方式三(通过FutureTask配合Thread类创建(会有返回值的线程))

FutureTask类是实现RunnableFuture接口的,而RunnableFuture接口又是同时实现Runnable, Future两个接口的。

所以这种方式创建线程任务,有点像实现Runnable接口,创建线程执行任务,最终都是会调用Thread类中的带参构造方法,最终线程执行task对象定义的任务代码,但是会又一个返回值,这个返回值可以被其他线程接收,用于线程之间调度任务的结果传参。
演示(第三种方式创建线程并运行)


线程Thread-0执行的代码就是task里面代码,外部的main线程接收Thread-0线程执行任务后的返回结果,并打印出来。其实在运行task.get()方法的时候,main线程一直都处于阻塞状态,等待Thread-0将执行的结果返回。
总结:
方法一是将线程与任务合并在一起(不推荐),而方法二是将线程与任务分开(推荐)。
用Runnable更容易与线程池等高级API配合。
用Runnable让任务摆脱了Thread继承类,使用起来更加灵活。
网友评论