zoukankan      html  css  js  c++  java
  • 多线程——Thread与Runnable的区别(28)

    视频:https://edu.aliyun.com/course/36/lesson/list?spm=5176.8764728.aliyun-edu-course-tab.2.W6yOMF

    首先,从使用形式上,使用Runnable实现多线程更好,因为避免了单继承问题,但除了这一点之外,Thread和Runnable之间也存在一些联系。观察Thread类的定义形式:

    public class Threadextends Objectimplements Runnable

    原来Thread类是Runnable接口的子类,那么Thread类也应该覆写了run()方法。

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

    public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
    }

    private void init有this.target = target;

    而之前target的定义是: private Runnable target;

    可以形成如下的类继承结构:

    所以,在多线程的处理上使用的是代理设计模式。除了上面的关系,在实际开发中使用Runnable还有一个特点:使用Runnable实现的多线程的程序类可以更好的描述出数据共享的概念(并不是说Thread不能)。
    (目标是产生若干个线程进行同一数据的处理操作)
    范例:使用Thread实现数据操作
    class MyThread extends Thread{   //是一个线程的主体类
        private int ticket=10;//一共10张票
    
        @Override
        public void run() {
            for(int x=0;x<20;x++){
                if(this.ticket>0){
                    System.out.println("卖票,ticket="+this.ticket--);
                }
            }
        }
    }
    public class ThreadTest {
        public static void main(String[] args) {
            new MyThread().start();
            new MyThread().start();
            new MyThread().start();
        }
    }
    
    

    此时只是想启动三个线程进行卖票处理。结果变为了各自卖各自的三张票。没有实现共享。分析内存关系:是各自自己的

    改为:
    class MyThread extends Thread{   //是一个线程的主体类
        private int ticket=10;//一共10张票
    
        @Override
        public void run() {
            for(int x=0;x<20;x++){
                if(this.ticket>0){
                    System.out.println("卖票,ticket="+this.ticket--);
                }
            }
        }
    }
    public class ThreadTest {
        public static void main(String[] args) {
    
            MyThread mt=new MyThread();
            new Thread(mt).start();
            new Thread(mt).start();
            new Thread(mt).start();
                   //即new Thread(new MyThread()).start();
        }
    }
    
    

    输出结果是:只有10张票,是实现了数据共享。但是相当有两个人都有水,但是这个人非要喝另外一个人的水,并不好。

    范例:使用Runnable实现共享

    class MyThread implements Runnable{   //是一个线程的主体类
        private int ticket=10;//一共10张票
    
        @Override
        public void run() {
            for(int x=0;x<20;x++){
                if(this.ticket>0){
                    System.out.println("卖票,ticket="+this.ticket--);
                }
            }
        }
    }
    public class ThreadTest {
        public static void main(String[] args) {
            MyThread mt=new MyThread();
            new Thread(mt).start();
            new Thread(mt).start();
            new Thread(mt).start();
        }
    }

    这时的MyThread是没有start方法的,所以是可以使用Thread的start方法的。实现了数据共享。输出结果也是共同卖10张票。

    Runnable能比Thread更好的实现数据共享的功能,但不是能不能的区别。又因为Runnable用的多,所以就能实现好的实现数据共享的。

  • 相关阅读:
    19.08.12 知识点的记录
    19.08.09 知识点的记录
    keil编译生成bin文件的方法
    python 虚拟环境virtualenv
    RT_Thread GD32F303 片上flash使用fal组件
    esp8266 deepsleep唤醒不工作打印
    5V 电源 适配器 空载耗电量 自身电量 消耗功率
    keil 更换jlink脚本版本
    ESP8266 NONOS SmartConfig配网(安信可公众号配网)
    windows安装esp开发环境
  • 原文地址:https://www.cnblogs.com/dengyt/p/6953906.html
Copyright © 2011-2022 走看看