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()" 来开启线程

             两种方法实现一样的工做可是它们之间仍是有一些区别的。spa

             它们之间的不一样是:线程

              1.咱们都知道,Java是单继承机制,不容许同时继承多个类。所以,当你继承Thread类(extends Thread)后,你就不能再继承其余类了。而你实现Runnable接口就不同了,你能够继承其余类了。code

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

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

              用一个例子来帮助咱们理解:继承

             

 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接口更好。

相关文章
相关标签/搜索