线程基础篇1:线程的3种创建方式,以及源码分析(超详细)

1、线程创建的三种方式

线程创建的三种方式有:实现runnable接口、继承Thread类、实现callable<V>类
其中runnable、Thread是无返回值,callable是有返回值。

其中Thread类最终也是实现的runnable接口,Thread类做了一层静态代理。

不了解静态代理的同学看源码理解起来会有点困难,建议看源码前先学习静态代理。

静态代理上链接

java中的静态代理-CSDN博客举一个简单的婚礼例子以及代码演示告诉你什么是静态代理,其实很简单。https://blog.csdn.net/rainingCSDN/article/details/143642900?spm=1001.2014.3001.5502

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()方法的原因了。

这就是我对线程的三种创建方式的理解,有问题的地方欢迎大家一起讨论!

后续会持续更新,欢迎大家一起讨论学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值