• Java中Runnable和Thread的区别


    概述

    Runnable 是接口。

    Thread 是类,且实现了Runnable接口。

    Thread部分源码

    public class Thread
        implements Runnable
    {
        private static class Caches
        {
     
            static final ConcurrentMap subclassAudits = new ConcurrentHashMap();
            static final ReferenceQueue subclassAuditsQueue = new ReferenceQueue();

    在使用Runnable定义的子类中没有start()方法,只有Thread类中才有。

    1 public interface Runnable
    2 {
    3  
    4     public abstract void run();
    5 }

    Thread类,有一个构造方法:public Thread(Runnable targer)

     1     public Thread(Runnable runnable)
     2     {
     3         daemon = false;
     4         stillborn = false;
     5         threadLocals = null;
     6         inheritableThreadLocals = null;
     7         threadStatus = 0;
     8         blockerLock = new Object();
     9         init(null, runnable, (new StringBuilder()).append("Thread-").append(nextThreadNum()).toString(), 0L);
    10     }

    此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程。

    使用情况

    在程序开发中只要是多线程肯定永远以实现Runnable接口为主。

    实现Runnable接口相比继承Thread类有如下好处:
    1、避免继承的局限,一个类可以继承多个接口。
    2、适合于资源的共享。

    实例

    以卖票为例,总共只有10张动车票了,全国3个窗口在卖。

     

     

    继承Thread类的方法

     1 package multithreading;
     2  
     3 public class MyThreadWithExtends extends Thread {
     4  
     5     private int tickets = 10;
     6  
     7     @Override
     8     public void run() {
     9  
    10         for (int i = 0; i <= 100; i++) {
    11             if(tickets>0){
    12                 System.out.println(Thread.currentThread().getName()+"--卖出票:" + tickets--);
    13             }
    14         }
    15     }
    16     
    17     
    18     public static void main(String[] args) {
    19         MyThreadWithExtends thread1 = new MyThreadWithExtends();
    20         MyThreadWithExtends thread2 = new MyThreadWithExtends();
    21         MyThreadWithExtends thread3 = new MyThreadWithExtends();
    22  
    23         thread1.start();
    24         thread2.start();
    25         thread3.start();
    26         
    27         //每个线程都独立,不共享资源,每个线程都卖出了10张票,总共卖出了30张。如果真卖票,就有问题了。
    28     }
    29  
    30 }

    运行结果:

    Thread-0--卖出票:10

    Thread-2--卖出票:10

    Thread-1--卖出票:10

    Thread-2--卖出票:9

    Thread-0--卖出票:9

    Thread-2--卖出票:8

    Thread-1--卖出票:9

    Thread-2--卖出票:7

    Thread-0--卖出票:8

    Thread-2--卖出票:6

    Thread-2--卖出票:5

    Thread-2--卖出票:4

    Thread-1--卖出票:8

    Thread-2--卖出票:3

    Thread-0--卖出票:7

    Thread-2--卖出票:2

    Thread-2--卖出票:1

    Thread-1--卖出票:7

    Thread-0--卖出票:6

    Thread-1--卖出票:6

    Thread-0--卖出票:5

    Thread-0--卖出票:4

    Thread-1--卖出票:5

    Thread-0--卖出票:3

    Thread-1--卖出票:4

    Thread-1--卖出票:3

    Thread-1--卖出票:2

    Thread-0--卖出票:2

    Thread-1--卖出票:1

    Thread-0--卖出票:1

    每个线程都独立,不共享资源,每个线程都卖出了10张票,总共卖出了30张。如果真卖票,就有问题了。

    实现Runnable接口方式

     1 package multithreading;
     2  
     3 public class MyThreadWithImplements implements Runnable {
     4  
     5     private int tickets = 10;
     6  
     7     @Override
     8     public void run() {
     9  
    10         for (int i = 0; i <= 100; i++) {
    11             if(tickets>0){
    12                 System.out.println(Thread.currentThread().getName()+"--卖出票:" + tickets--);
    13             }
    14         }
    15     }
    16     
    17     
    18     public static void main(String[] args) {
    19         MyThreadWithImplements myRunnable = new MyThreadWithImplements();
    20         Thread thread1 = new Thread(myRunnable, "窗口一");
    21         Thread thread2 = new Thread(myRunnable, "窗口二");
    22         Thread thread3 = new Thread(myRunnable, "窗口三");
    23  
    24         thread1.start();
    25         thread2.start();
    26         thread3.start();
    27     }
    28  
    29 }

    运行结果:

     

    窗口二--卖出票:10
    窗口三--卖出票:9
    窗口一--卖出票:8
    窗口三--卖出票:6
    窗口三--卖出票:4
    窗口三--卖出票:3
    窗口三--卖出票:2
    窗口三--卖出票:1
    窗口二--卖出票:7
    窗口一--卖出票:5

     

    每个线程共享了对象myRunnable的资源,卖出的总票数是对的,但是顺序是乱的,怎么办?

    见:同步关键词synchronized

  • 相关阅读:
    CentOS安装gotop
    oracle 非sys用户创建新用户 授权后 plsql看不到视图
    解决Eclipse+ADT连接夜神模拟器失败问题
    Ext JS v2.3.0 Ext.grid.ColumnModel renderer Record 获取列值
    vi常用快捷键汇总
    外键的变种
    完整性约束
    数据类型2
    数据类型
    表的操作
  • 原文地址:https://www.cnblogs.com/luxd/p/9812069.html
Copyright © 2020-2023  润新知