美文网首页
记一则 Thread 与 Runnable区别

记一则 Thread 与 Runnable区别

作者: 秋名山吴师傅 | 来源:发表于2021-04-16 09:46 被阅读0次

    最近重拾java进行学习。在学到Thread多线程的时候,demo给出了Thread与Runnable两种实现方式

    Thread

    public class ThreadAndRunnableDiff {
        public static void main(String[] args) {
            // 创建Thread进程
            Thread t = new MyThread();
          // 线程启动加入等待执行队列
            t.start();
        }
        public static class MyThread extends Thread {
            @Override
            public void run() {
                System.out.println("This is the thread, priority is:"+getPriority());
            }
        }
    }
    
    

    Runnable

    public class ThreadAndRunnableDiff {
        public static void main(String[] args) {
            Runnable r = new MyRunnable();
            Thread t = new Thread(r);
            t.start();
        }
        
        public static class MyRunnable implements Runnable{
            @Override
            public void run() {
                System.out.println("This is the runnable priority is");
            }
        }
    }
    

    我们从以上示例可以看出来两者有区别,但是写法上区别似乎并不大。
    Thread是直接new然后调用start方法,而Runnable是通过Thread类进行调用start

    角度 Thread Runnable
    本质 接口
    方法 拥有start方法和run方法 只有run方法
    创建一个唯一的对象并与之关联 多个线程共用一个对象
    内存 由于多个线程的对象对立所以内存占用比Runnable方式少 由于通过Thread类创建的线程都是可以共用一个Runnable对象所以内存占用比Thread少
    使用上的限制 由于Thread是要通过继承而来,而JAVA不支持多继承,所以一旦继承了Thread类后子类不允许再继承别的类 Runnable由于是接口,JAVA是允许多实现的,所以Runnable使用上的多样性会比Thread要更多

    源码本质区别

    Thread

    一般使用Thread的方式,我们是通过继承Thread类,并重写其run方法,我们来看看Thread构造干了什么 以我们Thread的代码例子来说

    1. new Thread()

    调用了Thread的构造我们来看看他的构造干了什么?

    public Thread() {
            this(null, null, "Thread-" + nextThreadNum(), 0);
        }
    

    看到他调用了当前的重载方法,传入了(null, null, "Thread-" + nextThreadNum(), 0)四个参数,我们继续追踪

    2.Thread(null, null, "Thread-" + nextThreadNum(), 0)

     public Thread(ThreadGroup group, Runnable target, String name,
                      long stackSize) {
            this(group, target, name, stackSize, null, true);
        }
    

    我们可以看到
    这个类参数注入了ThreadGroup,Runnable两个对象,我们继续追踪

    3. private Thread(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc,boolean inheritThreadLocals)

    private Thread(ThreadGroup g, Runnable target, String name,
            ........
      this.inheritedAccessControlContext =
                    acc != null ? acc : AccessController.getContext();
            this.target = target;
            setPriority(priority);
            .....
        }
    

    关键在于 this.target = target;
    其实Thread最终还是内部转化成Runnable并设置到类属性 this.target中

    4. 线程启动 start方法

    这里就一个重点方法调用start0

    5. 调用start0方法

    6. 重点来了run方法

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

    由于上面target是由于Runnable注入,所以这里最终就是调用target.run方法

    所以我可以认为,Thread最终还是会内部转化为Runnable方法进行调用

    由于我JAVA也是刚开始熟悉底层也不知道对不对还望各位看客多多提点

    相关文章

      网友评论

          本文标题:记一则 Thread 与 Runnable区别

          本文链接:https://www.haomeiwen.com/subject/ugddlltx.html