Java 中的“implements Runnable” 和“extends Thread”

    •       知识点

                  “implements Runnable” 和“extends Thread”的不同

         

    •       具体分析

              最近在学习Android中的Handler消息传递机制时,创建新线程有两种方式:一种是实现Runnable接口(implements Runnable)而另一种则是继承Thread类(extends Thread)。而这两种方式有什么异同呢?带着这个疑问,Google了一些资料出来,本着分享给大家同时也方便自己查阅复习,写一篇文章来记录它。

     

         

             首先看看这两种方式都是怎样的?

           

    复制代码
     1 public class ThreadA implements Runnable {
     2     public void run() {
     3         //Code
     4     }
     5 }
     6 //调用 "new Thread(threadA).start()" 来开启线程
     7 
     8 public class ThreadB extends Thread {
     9     public ThreadB() {
    10         super("ThreadB");
    11     }
    12     public void run() {
    13         //Code
    14     }
    15 }
    16 //调用 "threadB.start()" 来开启线程
    复制代码

                 两种方法实现同样的工作但是它们之间还是有一些区别的。

                 它们之间的不同是:

                  1.我们都知道,Java是单继承机制,不允许同时继承多个类。因此,当你继承Thread类(extends Thread)后,你就不能再继承其他类了。而你实现Runnable接口就不一样了,你可以继承其他类了。

                  2.当你继承Thread类时,你的每一个Thread对象创造不同的对象然后关联它们。

    而继承Runnable接口则不一样,多个线程共享一个对象。

                  用一个例子来帮助我们理解:

                 

    复制代码
     1 class ImplementsRunnable implements Runnable {
     2  
     3      private int counter = 0;
     4  
     5     public void run() {
     6     counter++;
     7     System.out.println("ImplementsRunnable : Counter : " + counter);
     8     }
     9  }
    10  
    11  class ExtendsThread extends Thread {
    12  
    13    private int counter = 0;
    14  
    15  public void run() {
    16    counter++;
    17    System.out.println("ExtendsThread : Counter : " + counter);
    18  }
    19  }
    20  
    21  public class ThreadVsRunnable {
    22  
    23  public static void main(String args[]) throws Exception {
    24  //多线程共享一个对象
    25    ImplementsRunnable rc = new ImplementsRunnable();
    26    Thread t1 = new Thread(rc);
    27    t1.start();
    28    Thread.sleep(1000); // 在开启下个线程前先等待1秒
    29    Thread t2 = new Thread(rc);
    30    t2.start();
    31    Thread.sleep(1000); // 在开启下个线程前先等待1秒
    32    Thread t3 = new Thread(rc);
    33    t3.start();
    34  
    35  //为每一个线程创造新的实例
    36    ExtendsThread tc1 = new ExtendsThread();
    37    tc1.start();
    38    Thread.sleep(1000); // 在开启下个线程前先等待1秒
    39    ExtendsThread tc2 = new ExtendsThread();
    40    tc2.start();
    41    Thread.sleep(1000); // 在开启下个线程前先等待1秒
    42    ExtendsThread tc3 = new ExtendsThread();
    43    tc3.start();
    44  }
    45  }
    复制代码

    运行结果:

               

              从运行的结果,我们可以看出。实现Runnable接口,只创建了一个类的实例,而且被多个线程共享了。因此Counter递增。而继承Thread类,你必须为每一个线程创建不同的实例。因此每个类的实例分配了不同的内存空间,每一个有不同的Counter,它们的值相同。这意味着没有增加因为没有一个对象的引用是相同的。

             那什么时候用Runnable接口呢?

             当你想要在一组线程中访问相同的资源时,使用Runnable接口。在这种情况下要避免使用Thread类,因为多对象的创建会占用更多的内存,会导致大的性能花费。

              PS:Thread类内部实现了Runnable接口

              最后,哪种方式最好用呢?

                 显而易见,当然是实现Runnable接口更好。

    标签:  AndroidJava
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值