Java 中的“implements Runnable” 和“extends Thread”
- 知识点
“implements Runnable” 和“extends Thread”的不同
- 具体分析
最近在学习Android中的Handler消息传递机制时,创建新线程有两种方式:一种是实现Runnable接口(implements Runnable)而另一种则是继承Thread类(extends Thread)。而这两种方式有什么异同呢?带着这个疑问,Google了一些资料出来,本着分享给大家同时也方便自己查阅复习,写一篇文章来记录它。
首先看看这两种方式都是怎样的?
public class ThreadA implements Runnable {
public void run() {
//Code
}
}
//调用 "new Thread(threadA).start()" 来开启线程 public class ThreadB extends Thread {
public ThreadB() {
super("ThreadB");
}
public void run() {
//Code
}
}
//调用 "threadB.start()" 来开启线程
两种方法实现同样的工作但是它们之间还是有一些区别的。
它们之间的不同是:
1.我们都知道,Java是单继承机制,不允许同时继承多个类。因此,当你继承Thread类(extends Thread)后,你就不能再继承其他类了。而你实现Runnable接口就不一样了,你可以继承其他类了。
2.当你继承Thread类时,你的每一个Thread对象创造不同的对象然后关联它们。
而继承Runnable接口则不一样,多个线程共享一个对象。
用一个例子来帮助我们理解:
class ImplementsRunnable implements Runnable { private int counter = 0; public void run() {
counter++;
System.out.println("ImplementsRunnable : Counter : " + counter);
}
} class ExtendsThread extends Thread { private int counter = 0; public void run() {
counter++;
System.out.println("ExtendsThread : Counter : " + counter);
}
} public class ThreadVsRunnable { public static void main(String args[]) throws Exception {
//多线程共享一个对象
ImplementsRunnable rc = new ImplementsRunnable();
Thread t1 = new Thread(rc);
t1.start();
Thread.sleep(1000); // 在开启下个线程前先等待1秒
Thread t2 = new Thread(rc);
t2.start();
Thread.sleep(1000); // 在开启下个线程前先等待1秒
Thread t3 = new Thread(rc);
t3.start(); //为每一个线程创造新的实例
ExtendsThread tc1 = new ExtendsThread();
tc1.start();
Thread.sleep(1000); // 在开启下个线程前先等待1秒
ExtendsThread tc2 = new ExtendsThread();
tc2.start();
Thread.sleep(1000); // 在开启下个线程前先等待1秒
ExtendsThread tc3 = new ExtendsThread();
tc3.start();
}
}
运行结果:
aaarticlea/png;base64,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" alt="" />
从运行的结果,我们可以看出。实现Runnable接口,只创建了一个类的实例,而且被多个线程共享了。因此Counter递增。而继承Thread类,你必须为每一个线程创建不同的实例。因此每个类的实例分配了不同的内存空间,每一个有不同的Counter,它们的值相同。这意味着没有增加因为没有一个对象的引用是相同的。
那什么时候用Runnable接口呢?
当你想要在一组线程中访问相同的资源时,使用Runnable接口。在这种情况下要避免使用Thread类,因为多对象的创建会占用更多的内存,会导致大的性能花费。
PS:Thread类内部实现了Runnable接口
最后,哪种方式最好用呢?
显而易见,当然是实现Runnable接口更好。
Java 中的“implements Runnable” 和“extends Thread”的更多相关文章
- Java 中的“implements Runnable” 和“extends Thread”(转)
知识点 “implements Runnable” 和“extends Thread”的不同 具体分析 最近在学习Android中的Handler消息传递机制时,创建新线程有两种方式:一种是实现Run ...
- Java 多线程实现接口Runnable和继承Thread区别(转)
Java 多线程实现接口Runnable和继承Thread区别 Java中有两种实现多线程的方式.一是直接继承Thread类,二是实现Runnable接口.那么这两种实现多线程的方式在应用上有什么区别 ...
- extends:类似于java中的继承特征,extends="struts-default"
extends:类似于java中的继承特征,extends="struts-default"就是继承struts-default.xml,它里面定义了许多跳转类型.拦截器等一些常用 ...
- java 中Handler 和Runnable 的使用 异步发送消息 转
public class MainActivity extends Activity { TextView text1, text2; Button button; Thread th; @Overr ...
- 在java中怎样实现多线程?线程的4种状态
一.在java中怎样实现多线程? extends Thread implement Runnable 方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 ...
- Java 使用线程方式Thread和Runnable,以及Thread与Runnable的区别
一. java中实现线程的方式有Thread和Runnable Thread: public class Thread1 extends Thread{ @Override public void r ...
- extend Thread 和 implements Runnable
原文地址:extend Thread 和 implements Runnable 一个Thread的实例只能产生一个线程 or: 同一实例(Runnable实例)的多个线程 look: public ...
- Java多线程系列--“基础篇”03之 Thread中start()和run()的区别
概要 Thread类包含start()和run()方法,它们的区别是什么?本章将对此作出解答.本章内容包括:start() 和 run()的区别说明start() 和 run()的区别示例start( ...
- java 多线程实现四种方式解析Thread,Runnable,Callable,ServiceExcutor,Synchronized ,ReentrantLock
1.Thread实现: import java.util.Date; import java.text.SimpleDateFormat; public class MyThread extends ...
随机推荐
- Linux命令(四)文件传输
1. 将当前目录下的test1.txt文件,复制到 /tmp/Douzi目录下,命名为test1.py 2. 将服务器/tmp/Douzi/hello.py复制到本地上,重命名为 hello_Do ...
- SQL语句(十四)子查询
--1. 使用IN关键字 --例1 查询系别人数不足5人的系别中学生的学号.姓名和系别 --系别人数不足5人的系别 ==>选择条件 select Sdept from Student Group ...
- C++的Enum hack
从一个例子开始吧 class Game { private: static const int GameTurn = 10; int scores[GameTurn]; }; 对于支持类内初始化的C+ ...
- supperset (python 2.7.12 + mysql)记录
网上看到superset,比较感兴趣,虚机上搭一下,记录操作过程. 版本信息:CentOS 6.6 + python 2.7.12 + mysql 5.1.73 + setuptools 36.5.0 ...
- CentOS7 关闭防火墙和selinux
本文将简单介绍在CentOS7上如何临时和永久关闭防火墙和selinux. 关闭防火墙 # 查看防火墙状态 [root@localhost ~]# systemctl status firewalld ...
- JQuery插件autocomplete使用说明文档
项目中有时会用到ajax自动补全查询,就像Google的搜索框中那样,输入汉字或者字母的首个字母,则包含这个汉字或者字母的相关条目会显示出来供用户选择,该插件就是实现这样的功能的.autocomple ...
- Javascript - Vue - 指令
指令 v-cloak 解决闪烁,闪烁是指在网速较慢的情况下可能会出现插值表达式{{}}还没有填充数据时会把该表达式直接显示在页面上,如果不希望看到插值表达式则可以使用v-cloak指令,具体做法如下 ...
- C/C++杂记:深入理解数据成员指针、函数成员指针
1. 数据成员指针 对于普通指针变量来说,其值是它所指向的地址,0表示空指针. 而对于数据成员指针变量来说,其值是数据成员所在地址相对于对象起始地址的偏移值,空指针用-1表示.例: 代码示例: str ...
- 如何动态修改windows下的host文件
事件背景:为了测试数据提交后,需要在另一个环境的多个测试节点下去验证测试数据是否添加成功,找了一大堆放法,用了比较笨的方法实现了.不多废话思路如下: 为了万无一失,先备份hosts文件内容: 1.读取 ...
- Python_oldboy_常用模块(九)
本节大纲: 模块介绍 time &datetime模块 random os sys shutil json & pickle shelve xml处理 yaml处理 configpar ...