线程相关(一)Thread 和 Runnable

2019-03-05  本文已影响0人  云鲸鱼rain

今天浏览到大牛的博客(https://blog.csdn.net/luoweifu/article/details/46673975)看到了线程部分,遂查资料记录。


Java提供了两种创建线程的方式,一种是实现Runnable接口,一种是继承Thread类。
首先用的时候就面临二选一问题,Java的话,自然是Runnable接口用的多一些,万一你写的类已经有了父类呢,Java单继承,多实现。

再说一下两者的关系。
Thread类本身实现了Runnable接口,所以无论用哪种方式,其实都是实现了Runnable接口。Runnable只有一个run方法,,最终线程执行时都是覆写的run方法。

上代码。
实现Runnable方法

package test;

public class ThreadA implements Runnable {
    
    private Thread thread;
    private String threadName;
    
    public ThreadA(String threadName) {
        thread = new Thread(this,threadName);//疑问点1
        this.threadName = threadName;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i ++) {
             System.out.println(threadName + ": " + i);
          }
    }
    
    public void start() {
          thread.start();
    }
    
}

继承Thread方法

package test;

public class ThreadB extends Thread {
    
    private String threadName;
    
    public ThreadB(String threadName) {
        super(threadName);//疑问点2
        this.threadName = threadName;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i ++) {
             System.out.println(this.getName() + ": " + i);
          }
    }
}

测试类

package test;

public class ThreadTest {
    
     public static void main(String args[]) {
          ThreadA threadA = new ThreadA("ThreadA");
          threadA.start();
          ThreadB threadB = new ThreadB("ThreadB");
          threadB.start();
     }
}

好,写出来创建线程的两种方法后,本着没有一行代码是废话的原则,开始理解每一行代码。发现了两个疑问点(在代码中有标)

疑问点1:

实现了Runnable接口的ThreadA类中的构造函数里thread = new Thread(this,threadName);为什么要传 this ?
经过查看API发现thread有好多构造函数(见下图),为什么偏偏要传this。

英文版
中文版
疑问点的构造函数具体解释

当我去掉this,只传线程名的时候,发现输出不了任何内容。
在看了API之后,告诉我很重要的一点。
首先明白,最终目的我们都要执行复写的run方法,那么如何找到run方法?就靠这个参数了,target - 其 run 方法被调用的对象。(这里也是之后写线程同步关键的地方!)
所以我去掉this不输出内容的原因是:找不到执行哪个run方法。

疑问点2:

继承了Thread的类ThreadB中的构造函数里为什么要加 super(threadName);
总所周知,super(); 是默认写出来的,需要显式的写出来的情况无非就是需要调用父类有参数的构造函数。所以这里为什么要把线程名给父类Thread?
super(threadName);去掉之后,run还是可以的,但是,线程名变成了自动分配的线程名,而非ThreadB线程名。所以super(threadName)实际上是给此线程起名。

上一篇 下一篇

猜你喜欢

热点阅读