创建线程的疑惑:new Thread()和new Thread(Runnable接口实现类对象)的区别

最近在学习多线程,对于书本上关于this.getName()和Thread.currentThread().getName()的案例有些困惑,今天专门研究了一下得出了如下的结论:

代码如下:

public class ThreadDemo2 {
    public static void main(String[] args) {
        myThread myThread=new myThread();
        myThread.setName("A");
        myThread.start();

    }
}

class myThread extends Thread{
    @Override
    public void run() {
        System.out.println("返回正在执行该代码的线程名称:"+Thread.currentThread().getName());
        System.out.println("当前线程对象的名称:"+this.getName());
    }
}

执行这段代码的结果为:

                                         返回正在执行该代码的线程名称:A
                                         当前线程对象的名称:A

此时我们可以看到this.getName()和Thread.currentThread().getName()的执行结果是一样的。

接下来我们看下Thread类中的run()方法是如何定义的:

@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

方法中的target是在创建对象时候传的Runnable接口实现类的对象,所以接下来我们再来看一个例子,将上面的代码稍作修改:

public class ThreadDemo2 {
    public static void main(String[] args) {
        myThread myThread=new myThread();
        Thread thread=new Thread(myThread);
        thread.setName("A");
        myThread.setName("B");
        thread.start();

    }
}

此时的运行结果为:

                                返回正在执行该代码的线程名称:A
                                当前线程对象的名称:B

到这里,可能还是会有些同学有些迷茫,为什么会出现这样的结果?OK,我们继续往下分析,

java中创建多线程的方式有两种,方法1 :继承Thread类,这种方法,我们暂且不太多关注。

                    方法2 :实现Runnable接口,并将实现类对象以参数的形式传递到Thread对象的创建过程中,代码如下:

public class ThreadDemo2 {
    public static void main(String[] args) {
        implRunnable impl=new implRunnable();
        Thread thread1=new Thread(impl);
        thread1.setName("C");
        thread1.start();
    }
}

class implRunnable implements Runnable{
    public void run() {
    }
}

我们可以看到这种创建线程的方式和方法一结果一样的,至于两者的优劣,可以思考下java的单根继承的特性即可知晓。

同时,我们继续看下Thread类的源码:

我只截取了这一点,但是这一点就足以说明问题了,前面遇到的this.getName()和Thread.currentThread().getName()的结果不同,是因为我们将Thread对象作为了Runnable接口实现类以参数的形式传递给了创建Thread对象的过程,这句话可能会有一点点的绕口,但是仔细的分析一下,还是可以明白的。

下面我们将上面出现结果不一致问题的代码再加两行处理:

public static void main(String[] args) {
    myThread myThread=new myThread();
    Thread thread=new Thread(myThread);
    thread.setName("A");
    myThread.setName("B");
    thread.start();
    System.out.println("myThread.hashCode()-->"+myThread.hashCode());
    System.out.println("thread.hashCode()-->"+thread.hashCode());
}

运行结果:

                返回正在执行该代码的线程名称:A
               当前线程对象的名称:B
               myThread.toString()-->1215070805
               thread.toString()-->1273020312

之所以会出现结果不同,那是因为这完全是两个不同的对象造成,或者你也可以理解为是两个线程,只是有一个线程虽然创建了但是并没有开启。

已上所言皆是个人见解,如有不妥,还望各位大神多多指导。祝所有人生活快乐。

你可能感兴趣的:(创建线程的疑惑:new Thread()和new Thread(Runnable接口实现类对象)的区别)