美文网首页基础知识
多线程两种实现方式的区别

多线程两种实现方式的区别

作者: 秋笙fine | 来源:发表于2019-01-16 02:14 被阅读54次

这是一道面试题。这两种方式有哪种区别?
Runnable将数据共享这一特点完美诠释。

首先一定要明确的是,使用我们的Runnable接口与Thread类相比,解决了单继承的定义局限,所以在优先级上已经确定使用Runnable接口。
首先看jdk源码中Thread类定义:

public class Thread extends Object implements Runnable

发现Thread类实现了Runnable接口,那么这样一来就变为了以下形式。

image.png

我们可以看出,Runnable接口实现多线程其实很像代理模式的应用。很好的起到了设计模式中原则中的迪米特原则。之所以是"像",因为如果是代理设计模式,那么客户端调用的应该是接口里面提供的run()方法。

除了以上联系之外,使用Runnable接口可以比Thread类更好的描述出数据共享这一个概念,此时的数据共享指的是多个线程访问同一资源的操作。
范例:观察代码(每一个线程对象都必须通过start()启动)

package TestDemo;



class MyThread extends Thread{
    private int ticket=10;//这里的变量会压入局部变量表 因为并没有用static声明
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(this.ticket>0){
                System.out.println("sell,ticket="+this.ticket--);
            }
        }
    }
}

public class TestDemo{
    
    public static void main(String[] args) {
        MyThread thread1=new MyThread();
        MyThread thread2=new MyThread();
        MyThread thread3=new MyThread();

        thread1.start();
        thread2.start();
        thread3.start();
    }
}
image.png
结果三个thread类都在卖各自的10张票,这是由于我们并没有给ticket设置为static变量,所以这个数据没有被录入元数据区,而被压入了局部变量表,在执行实例化操作后,各自生成了一块堆内存指向,此时并不存在数据共享这一概念。

在JVM内存模型基础上,我们可以看这张基于多线程的内存模型。

image.png
也很好的诠释了这一点。而Runnable就完美实现了这张内存模型图,我们可以把主存看作是MyThread类中的元数据,三个new Thread类匿名内部类对象实例看作3块工作内存。

范例:利用Runnable实现。

package TestDemo;



class MyThread implements Runnable{
    private int ticket=10;//这里的变量会压入局部变量表 因为并没有用static声明
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if(this.ticket>0){
                System.out.println("sell,ticket="+this.ticket--);
            }
        }
    }
}

public class TestDemo{
    
    public static void main(String[] args) {
        MyThread mt=new MyThread();
        new Thread(mt).start();
        new Thread(mt).start();
        new Thread(mt).start();
    
    }
}
image.png
原理分析:这是由于三个不同的栈都指向了同一块堆内存对象,确保了他们操作的是同一个实例化对象。

因而当多个线程访问同一资源时候,我们使用Runnable更好的描述了数据共享这个概念(本质上是JVM虚拟栈是否指向同一块堆内存)

总结:请解释Thread类与Runnable接口实现多线程的区别(请解释多线程两种实现方式区别)?

Thread类是Runnable接口的子类,使用Runnable接口实现多线程可以避免单继承的局限性。
Runnable接口实现的多线程可以比Thread类实现的多线程更加清楚的描述数据共享的概念(本质上是JVM虚拟栈是否指向同一块堆内存)
可以将JVM内存布局以及基于多线程的内存模型画出来。

以及将两种多线程实现方式,白板编程出来。

关注公众号Code In Java,Java学习图谱,数据结构与算法资料等各种资料都可以在后台获取。等你哦~

相关文章

  • 多线程(二):实现多线程的两种方式

    一,多线程的实现方式 方式一: 继承Thread类 方式二: 实现Runable接口(推荐) 二,两种方式的区别 ...

  • 2.编写多线程

    1.实现多线程的两种方式 继承Thread类 实现Runnable接口 这两种方式基本没啥区别,因为Java不能多...

  • 《每天进步一点点》DAY6:多线程

    多线程实现方式(两种方式的区别) 查看源码的区别:a.继承Thread : 由于子类重写了Thread类的run(...

  • 两种建立多线程的方式

    Thread和Runnable实现多线程的区别 Java中实现多线程有两种方法:继承Thread、实现Runnab...

  • 3-Java中如何创建线程

    Runnable和Thread实现多线程的区别 Java中实现多线程有两种方法:继承Thread类、实现Runna...

  • 线程池

    线程 创建线程有两种方式: 1、继承Thread类2、实现Runnable接口 区别在于:主要区别在于在多线程访问...

  • Java中Runnable和Thread的区别分析

    Java中Runnable和Thread的区别分析 在java中可有两种方式实现多线程,一种是继承Thread类,...

  • Java中的多线程实现方式

    Java中的多线程实现方式 在我们的开发的过程中,常常会碰到多线程的问题,对于多线程的实现方式主要有两种:实现Ru...

  • 多线程两种实现方式的区别

    这是一道面试题。这两种方式有哪种区别?Runnable将数据共享这一特点完美诠释。 首先一定要明确的是,使用我们的...

  • Java线程相关学习笔记

    Java 线程相关 如何创建线程(两种方式,区别,使用场景)线程状态调度多线程数据共享(会有什么问题,如何实现共享...

网友评论

    本文标题:多线程两种实现方式的区别

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