JAVA并发编程——1、线程的“几种”实现方式

实现线程的几种方法

学习并发编程的第一步自然是学习怎样创建一个线程,以下举例了几种常用的线程创建方式

继承Thread类

第一种方式是大家最熟悉的通过继承Threa类,并重写其中的run()方法来实现一个线程的创建。

class ThreadTest extends Thread{
    @Override
    public void run() {
        System.out.println("say something");
    }
}

实现Runnable接口

第二种方式便是通过实现Runnable接口,并重写其中run()方法

class RunnableTest implements Runnable{
    @Override
    public void run() {
        System.out.println("say something");
    }
}

这个方法通过将实现了Runnable接口的类的实例传入Thread类中便实现了线程的创建。

其实我们可以从源码中看出,Thread类也实现了Runnable接口。不难看出这其中有静态代理模式的存在。Runnable在其中扮演的是一个定义任务的角色。

Callable创建

Callable接口是java.util.concurrent包下的一个接口。与其他不同的是:1、会抛出Exception异常。2、它是带有有返回值的返回值类型与其泛型类型相同。有返回值的好处也很明显。我们获取线程运行的结果不用再通过传统的写接口回调等方式。而是通过Callable和Future、FutureTask,来实现返回值的调用。

class ThreadCallAble implements Callable<Boolean>{
    @Override
    public Boolean call() throws Exception {
        for (int i = 0 ; i<=100 ; i++){
            System.out.println("say something");
        }
        return true;
    }
}

//主线程
psvm{
//        创建执行服务
        ExecutorService executorService = Executors.newFixedThreadPool(10);
//        提交执行
        Future<Boolean> submit = executorService.submit(new ThreadCallAble());
//        获取结果
        Boolean aBoolean = submit.get();
        System.out.println(aBoolean);
//        关闭服务
        executorService.shutdownNow();
}

其他创建方式

还有一些其他创建方式例如:
线程池创建
Timer定时器创建等
这里就不在赘述

本质到底有几种线程创建方式

其实创建线程方式本质上只有一种:Thread类创建。
从源码剖析:
1、线程池方法:相对于线程池而言,创建线程的默认方法是采用线程工厂:DefaultThreadFactory来创建,其中最合心的就是线程创建方法newThread()
这个方法从本质上就是new Thread()。并且给线程设置好一些默认值(线程名、守护线程、优先级等)但本质还是调用了Thread类的构造函数所以并没有脱离Thread类创建的范畴,只是在其基础上做了包装。
DefaultThreadFactory是Executors的内部类
newThread方法
2、Callable
Callable接口其实和Runnable接口很像。他们都是对线程要做的任务的一个定义。Callable接口的实现类被实例化出来后并不是直接使用,而是通过submit()方法提交给线程池由线程池完成线程的创建和使用。所以流程上和上面的线程池创建差不多也不能算一种单独的方式
3、定时器TImer
也不用多说,从源码上看Timer类继承自TimerThread类,而TimerThread又继承自Thread类。所以本质并无区别
4、Runnable接口
Runnable接口与Thread类之间其实是一种静态代理的关系。实现Runnable接口其实就是描述线程要做的任务并不是创建线程(从要把Runable接口实现类的实例传递给Thread构造也可以看出来)

总结

其实我们理解的很多种创建线程的方式并不存在。或者说并不是多种方式,本质上线程的创建在只有一种方式——Thread类创建。
而真正有多种方式的实际上是实现(定义)线程执行内容的方式。

实现Runnable接口还是继承Thread类

为什么说实现Runnable接口的方式优于继承Thread类,有以下几个原因
1、Java不支持多继承,继承了Thread类必然会限制类的可拓展性。
2、解耦,可以实现Thread只负责线程的设置和启动,而实现Runnable接口的类完成线程功能的定义
3、可以在线程池中固定一些线程完成特定任务。而不是一些特定任务频繁创建线程销毁线程导致资源的浪费。实现性能的提高。
第一次写博文写的不好还请谅解 有错误还请多多指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值