start() && run()、Runnable && Callable、Thread && Runnable

线程的定义:“线程是一种轻量级的进程,是由进程派生出来的子任务,它是程序执行的一个路径;每个线程都有自己的局部变量表、程序计数器(指向真正执行的指令指针)以及各自的生命周期”

start() && run()
要搞清楚这个问题,需要我们明确“线程的执行单元”与“线程”是两个不同的概念。在JAVA中通过Thread类重写的run()方法是线程的执行单元,而通过调用start()方法才是真正启动了一个线程,start()方法会使得该线程开始执行,java虚拟机会去调用该线程的run()方法

根据java api,Runnable接口只有一个方法,就是run(),start()方法是Thread的类方法

在不少关于JAVA线程的软文或者书籍中,经常会提到,创建线程有两种方式:
第一种是构造一个Thread
第二种是实现Runnable接口。
通过上面的分析,这种说法其实是不严谨的。在JDK中代表线程的只有Thread类,而Runnable接口只是简单定义了一个无参数返回值的run方法。而我们知道run方法只是定义了线程的执行单元,而并非直接开启了线程资源,只有Thread方法的start()方法才可以启动一个线程。

所以,如果面试中有人问你在JAVA中实现线程的方式有哪些?应该告诉他准确答案:“在JAVA中创建线程只有一种方式,那就是构造Thread类。而实现线程的执行单元则有两种方式,第一种是重写Thread类的run方法;第二种是实现Runnable接口的run方法,并且将Runnable实例用作构造Thread的参数”

Runnable && Callable
相同点

两者都是接口;(废话)
两者都可用来编写多线程程序;
两者都需要调用Thread.start()启动线程;

不同点

两者最大的不同点是:实现Callable接口的任务线程能返回执行结果;而实现Runnable接口的任务线程不能返回结果;
Callable接口的call()方法允许抛出异常;而Runnable接口的run()方法的异常只能在内部消化,不能继续上抛;

Thread && Runnable

1、效果上没区别,写法上的区别而已。
2、没有可比性,Thread实现了Runnable接口并进行了扩展,我们通常拿来进行比较只是写法上的比较,而Thread和Runnable的实质是实现的关系,不是同类东西。

  • Runnable适合多个相同的程序代码的线程去处理同一个资源;
  • 可以避免Java中的单继承的限制,增加程序的健壮性,代码可以被多个线程共享,代码和数据独立
  • 线程池只能放入实现Runnable 类线程,不能直接放入继承Thread的类

注意点:
Callable接口支持返回执行结果,此时需要调用FutureTask.get()方法实现,此方法会阻塞主线程直到获取‘将来’结果;当不调用此方法时,主线程不会阻塞

参考 :线程池的设计原理是什么?

你可能感兴趣的:(start() && run()、Runnable && Callable、Thread && Runnable)