在看很多的关于java创建新线程的博客中,发现有的说创建新的线程有两种方式,有的说是三种方式。但是到底是哪一种是正确的呢 ?
两种创建方式: 一种是将类声明为Thread的子类,该类应重写Thread类的run方法,另一种是实现Runnable接口,并实现run方法。三种创建方式: 在前面两种的方式+ 第三种:实现Callable< V > 接口,实现call方法。
首先是从这两种结论可以看出:争论是在第三种实现Callable接口的方式 是不是java创建线程的方式!
我还是先看脚踏实地看下这三种创建新的线程的方式:
一. 将类声明为Thread的子类,并重写Thread类的run方法
private static class ThreadSon extends Thread{
@Override
public void run(){
System.out.println("thread子方法:" + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
System.out.println("main方法:" + Thread.currentThread().getName());
ThreadSon threadSon = new ThreadSon();
threadSon.start();
}
执行结果: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200502200452804.png)
二. 实现Runnable接口,重写fun方法
private static class RunnableSon implements Runnable{
@Override
public void run() {
System.out.println("runable子方法:" + Thread.currentThread().getName());
}
}
public static void main(String[] args) {
System.out.println("main方法:" + Thread.currentThread().getName());
RunnableSon runnableSon = new RunnableSon();
Thread t = new Thread(runnableSon);
t.start();
}
执行结果: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200502201555264.png)
三. 实现Callable接口,实现call方法
private static class CallableSon implements Callable{
@Override
public Integer call() throws Exception {
System.out.println("子线程名称:" + Thread.currentThread().getName());
return 123456;
}
}
public static void main(String[] args) {
System.out.println("主线程:" + Thread.currentThread().getName());
CallableSon callableSon = new CallableSon();
FutureTask futureTask = new FutureTask(callableSon);
Thread thread = new Thread(futureTask);
thread.start();
}
执行结果: 从上面的运行结果上看,这三种方式都创建了新的线程,那么 “三种创建方式”的结论是正确的。然而事实真的是这样的吗?????
四. 查看JDK文档
由上图可知,JDK官方文档上明确说明,有两种方式创建一个新的执行线程。 由下图可知,这两种方式,一种是继承Thread,重写run方法;另一种实现Runnable接口,实现run方法。 由此说明,java创建新的线程的方式是两种!!! ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200502230400390.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4Njc1Mzcz,size_16,color_FFFFFF,t_70)
五. 探究:为什么实现Callable接口的方式不被JDK官方承认这是一种新的创建线程的方式呢??
private static class RunnableSon implements Runnable{
@Override
public void run() {
System.out.println("runnable子方法:" + Thread.currentThread().getName());
}
}
private static class CallableSon implements Callable{
@Override
public Integer call() throws Exception {
System.out.println("callable子方法:" + Thread.currentThread().getName());
return 123456;
}
}
public static void main(String[] args) {
System.out.println("主线程:" + Thread.currentThread().getName());
CallableSon callableSon = new CallableSon();
FutureTask futureTask = new FutureTask(callableSon);
Thread thread = new Thread(futureTask);
thread.start();
RunnableSon runnableSon = new RunnableSon();
Thread runThread = new Thread(runnableSon);
runThread.start();
}
由上面的代码可知:Runnable和Callable都是通过new Thread(Runnable target)创建线程的,下面代码是Thread的含参构造,并初始化一个线程。
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
下面是Callable的官方说明,Callable类似与Runnable,并由他们共同使用同一个初始化线程的方法。又因为Runnable Jdk1.0 就已经出现,而Callable Jdk1.5才出现,因此JDK官方也只是把他们俩算作一种创建线程的方式。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200502232419428.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4Njc1Mzcz,size_16,color_FFFFFF,t_70)
6. java 创建新的线程的方式是两种:一种是将类声明为Thread的子类,该类应重写Thread类的run方法,另一种是实现Runnable接口,并实现run方法。
以上第五部分是本人查看源码的理解:如有偏差或错误,请不吝赐教!!!
|