1、线程创建的三种方式
线程创建的三种方式有:实现runnable接口、继承Thread类、实现callable<V>类
其中runnable、Thread是无返回值,callable是有返回值。
其中Thread类最终也是实现的runnable接口,Thread类做了一层静态代理。
不了解静态代理的同学看源码理解起来会有点困难,建议看源码前先学习静态代理。
静态代理上链接
2、代码演示
2.1、 继承Thread类
public class ThreadStudy extends Thread { //继承Thread类
@Override
public void run() { //实现方法
for (int i = 0;i < 200;i++){
System.out.println("the thread run! :" + i);
}
}
public static void main(String[] args) {
ThreadStudy threadStudy = new ThreadStudy(); //创建线程对象
threadStudy.start(); //开启线程
for (int i=0; i<200; i++){
System.out.println("the mainMethod run! :" + i);
}
}
}
2.2、实现Runnable接口
class RunnableStudyTest implements Runnable{ //实现接口
@Override
public void run() { //实现接口里面的方法
System.out.println("helloRunnable");
}
public static void main(String[] args) {
RunnableStudyTest runnableStudyTest = new RunnableStudyTest(); //创建线程对象
new Thread(runnableStudyTest).start(); //开启线程
System.out.println("helloMain");
}
}
2.3、实现Callable<V>接口(有返回值,实际中使用较少)
public class CallableStudy {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread(1000)); //创建线程对象
new Thread(futureTask).start(); //开启线程
System.out.println(futureTask.get()); //获取线程对象返回的值,输出结果为1000
}
}
class MyThread implements Callable<Integer>{ //实现Callable接口
int i;
public MyThread(int i) {
this.i = i;
}
@Override //实现方法
public Integer call() throws Exception {
return i;
}
}
总结:线程的创建其实很简单,四步走
继承或实现接口->实现方法->创建线程对象->开启线程
3、原码分析
3.1、继承Thread类
我们点进去Thread类中会发现,实际上Thread实现的是Runnable接口

我们再点进去实现的Runnable接口,其实就只有一个抽象的run方法,所以我们创建线程的时候必须要去实现这个run方法

Thread类中有个start方法,就是供我们开启线程用的,所以在该方式下,我们直接.start的方式开启就可以了。

3.2、实现Runnable接口
我们刚刚学到,实现Runnable接口开启线程需要用到Thread对象里面的start()方法的,是因为Thread方法做了一层静态代理,我们点进去源码看看。


我们点进去这个方法中会看到,我们需要传一个Runnable对象,再过通过this构造函数方法把该Runnable对象的值赋值给当前Thread对象。
3.3、实现Callable<V>接口
我们点击进去Callable接口,发现只有一个方法。其实这和Runnable接口很类似,只是多了一个返回值,最终也是需要通过Thread这个静态代理来开启线程的。

我们刚刚学到,开启Callable线程需要创建一个FutureTask对象,并把当前的Callable线程传进去


其实我们点进去FutureTask类会发现,其实该来最终实现的也是Runnable接口


这就是为什么开启该线程和Runnable方法一样都是需要创建Thread对象用里面的start()方法的原因了。
这就是我对线程的三种创建方式的理解,有问题的地方欢迎大家一起讨论!
后续会持续更新,欢迎大家一起讨论学习。
&spm=1001.2101.3001.5002&articleId=143640929&d=1&t=3&u=a7e43bf271864703a26b20dfed32070c)
6004

被折叠的 条评论
为什么被折叠?



