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

时间: 2024-10-12 12:03:54

Java 中的“implements Runnable” 和“extends Thread”的相关文章

Java 中的“implements Runnable” 和“extends Thread”(转)

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

java 中Handler 和Runnable 的使用 异步发送消息 转

public class MainActivity extends Activity { TextView text1, text2; Button button; Thread th; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text1 = (TextView

Java中多线程的回顾---学习笔记(二)

线程的创建方式有两种: implements Runnable和extends Thread. 继承Thread类: package com.test.threadtest; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bu

在java中怎样实现多线程?线程的4种状态

一.在java中怎样实现多线程? extends Thread implement Runnable 方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可. 下面是一个例子: public class MyThread extends Thread { int count= 1, number; public MyThread(int num) { number = num; System.out.printl

Java中的线程Thread解析及用途

Java中的线程 进程和线程 在并发性程序中,有两个基本的执行单元:进程和线程.在Java编程语言中,并发编程大多数情况下都是和线程相关.然而,进程也是很重要的. 一个计算机系统中通常都有很多活动的进程和线程.这一点即使是在只有一个执行核心,并且在给定时刻只能执行一个线程的系统中都是存在的.单一核心的处理时间是由整个操作系统的"时间片"特性来在众多的进程和线程中共享的. 现在,计算机系统中有多个处理器或者是有多核处理器的情况越来越普遍.这就大大增强了系统执行多个进程和线程的并发性. 进

java 多线程实现四种方式解析Thread,Runnable,Callable,ServiceExcutor,Synchronized ,ReentrantLock

1.Thread实现: import java.util.Date; import java.text.SimpleDateFormat; public class MyThread extends Thread{ @Override public void run(){ SimpleDateFormat strf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 String d = strf.format(new Date

Java中如何优雅正确的终止线程

Java中终止线程的方式主要有三种: 1.使用stop()方法,已被弃用.原因是:stop()是立即终止,会导致一些数据被到处理一部分就会被终止,而用户并不知道哪些数据被处理,哪些没有被处理,产生了不完整的"残疾"数据,不符合完整性,所以被废弃.So, forget it! 2.使用volatile标志位 看一个简单的例子: 首先,实现一个Runnable接口,在其中定义volatile标志位,在run()方法中使用标志位控制程序运行 public class MyRunnable i

黑马程序员------Java中多线程学习总结(一)

Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! 一.多线程的概念 进程:是一种“自包容”的运行程序,有自己的地址空间. 基于进程的特点是允许计算机同时运行两个或更多的程序 线程:是进程内部单一的一个顺序控制流 . 基于线程的多任务处理环境中,线程是最小的处理单位. 在Java中,一个应用程序可以包含多个线程.每个线程执行特定的任务,并可与其他线程并发执行.多线程使系统的空转时间减少,提高了CPU的利用率.多线程编程隐藏了CPU在任务之间切换的事实. 二.创建

Java中Socket通信的知识回顾---学习笔记

两台计算机进行通信的基本前提: (1)IP地址: 每台计算机都有自己独一无二的IP地址,根据IP地址判断与哪台计算机进行通信. (2)端口号: 每个应用程序都有自己专属的端口,根据端口号判断与计算机中的哪个应用程序进行通信. 说明: <1>用于区分不同应用程序 <2>端口号的范围:0-65535,其中0-1023是为系统保留的端口号 <3>常用的协议的端口号: http:80 ftp:21 telnet:23 <4>IP地址+端口号=Socket,Socke