Java中Runnable和Thread的区别
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。
下面看例子:
package org.thread.demo;
class MyThread extends Thread{
private String name;
public MyThread(String name) {
super();
this.name = name;
}
public void run(){
for(int i=0;i<10;i++){
System.out.println("线程开始:"+this.name+",i="+i);
}
}
} package org.thread.demo;
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread mt1=new MyThread("线程a");
MyThread mt2=new MyThread("线程b");
mt1.run();
mt2.run();
}
}
但是,此时结果很有规律,先第一个对象执行,然后第二个对象执行,并没有相互运行。在JDK的文档中可以发现,一旦调用start()方法,则会通过JVM找到run()方法。下面启动start()方法启动线程:
package org.thread.demo;
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread mt1=new MyThread("线程a");
MyThread mt2=new MyThread("线程b");
mt1.start();
mt2.start();
}
};
这样程序可以正常完成交互式运行。那么为啥非要使用start();方法启动多线程呢?
在JDK的安装路径下,src.zip是全部的java源程序,通过此代码找到Thread中的start()方法的定义,可以发现此方法中使用了private native void start0();其中native关键字表示可以调用操作系统的底层函数,那么这样的技术成为JNI技术(java Native Interface)
Runnable接口
在实际开发中一个多线程的操作很少使用Thread类,而是通过Runnable接口完成。
public interface Runnable{
public void run();
}
例子:
package org.runnable.demo;
class MyThread implements Runnable{
private String name;
public MyThread(String name) {
this.name = name;
}
public void run(){
for(int i=0;i<100;i++){
System.out.println("线程开始:"+this.name+",i="+i);
}
}
};
但是在使用Runnable定义的子类中没有start()方法,只有Thread类中才有。此时观察Thread类,有一个构造方法:public Thread(Runnable targer)此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程。(start()可以协调系统的资源):
package org.runnable.demo;
import org.runnable.demo.MyThread;
public class ThreadDemo01 {
public static void main(String[] args) {
MyThread mt1=new MyThread("线程a");
MyThread mt2=new MyThread("线程b");
new Thread(mt1).start();
new Thread(mt2).start();
}
}
两种实现方式的区别和联系:
在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下好处:
- 避免点继承的局限,一个类可以继承多个接口。
- 适合于资源的共享
以卖票程序为例,通过Thread类完成:
package org.demo.dff;
class MyThread extends Thread{
private int ticket=10;
public void run(){
for(int i=0;i<20;i++){
if(this.ticket>0){
System.out.println("卖票:ticket"+this.ticket--);
}
}
}
};
下面通过三个线程对象,同时卖票:
package org.demo.dff;
public class ThreadTicket {
public static void main(String[] args) {
MyThread mt1=new MyThread();
MyThread mt2=new MyThread();
MyThread mt3=new MyThread();
mt1.start();//每个线程都各卖了10张,共卖了30张票
mt2.start();//但实际只有10张票,每个线程都卖自己的票
mt3.start();//没有达到资源共享
}
}
如果用Runnable就可以实现资源共享,下面看例子:
package org.demo.runnable;
class MyThread implements Runnable{
private int ticket=10;
public void run(){
for(int i=0;i<20;i++){
if(this.ticket>0){
System.out.println("卖票:ticket"+this.ticket--);
}
}
}
}
package org.demo.runnable;
public class RunnableTicket {
public static void main(String[] args) {
MyThread mt=new MyThread();
new Thread(mt).start();//同一个mt,但是在Thread中就不可以,如果用同一
new Thread(mt).start();//个实例化对象mt,就会出现异常
new Thread(mt).start();
}
};
虽然现在程序中有三个线程,但是一共卖了10张票,也就是说使用Runnable实现多线程可以达到资源共享目的。
Runnable接口和Thread之间的联系:
public class Thread extends Object implements Runnable
发现Thread类也是Runnable接口的子类。
【编辑推荐】
Java中Runnable和Thread的区别的更多相关文章
- Java中Runnable和Thread的区别(转)
http://developer.51cto.com/art/201203/321042.htm 第一种方式:使用Runnable接口创建线程 第二种方式:直接继承Thread类创建对象 使用Runn ...
- java中Runnable和Callable的区别
文章目录 运行机制 返回值的不同 Exception处理 java中Runnable和Callable的区别 在java的多线程开发中Runnable一直以来都是多线程的核心,而Callable是ja ...
- Java中Runnable和Thread
java中有两种实现多线程的方式:一种是继承Thread类,一种是实现Runnable接口. 1.java启动线程为什么使用start函数呢? 在JDK的安装路径下,src.zip是全部的java源程 ...
- java中fail-fast 和 fail-safe的区别
java中fail-fast 和 fail-safe的区别 原文地址:http://javahungry.blogspot.com/2014/04/fail-fast-iterator-vs-fa ...
- 怎么在java中关闭一个thread
怎么在java中关闭一个thread 我们经常需要在java中用到thread,我们知道thread有一个start()方法可以开启一个线程.那么怎么关闭这个线程呢? 有人会说可以用Thread.st ...
- java中wait和sleep的区别
文章目录 Wait和sleep的区别 唤醒wait和sleep java中wait和sleep的区别 在本篇文章中,我们将会讨论一下java中wait()和sleep()方法的区别.并讨论一下怎么使用 ...
- Java中Set Map List 的区别
java中set map list的区别: 都是集合接口 简要说明 set --其中的值不允许重复,无序的数据结构 list --其中的值允许重复,因为其为有序的数据结构 map--成对的数据结构 ...
- Java中Comparable和Comparator接口区别分析
Java中Comparable和Comparator接口区别分析 来源:码农网 | 时间:2015-03-16 10:25:20 | 阅读数:8902 [导读] 本文要来详细分析一下Java中Comp ...
- 转:Java中abstract和interface的区别
转自:Java中abstract和interface的区别 abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java ...
随机推荐
- 手机app软件开发有什么需要注意的细节?
在做手机产品设计的过程中,遇到很多看似很小,且很容易被忽略的问题,正是这些手机应用软件开发小问题,一次次的撩拨用户的耐心,让用户对你的产品心生怨念.刚出道的朋友没有经过实战,对细节注意不多,往往都会遇 ...
- Dynamic Programming [Algorithm]
今天学习动态规划01背包问题,从一篇非常不错的文章中学习甚多.转载于此,感谢作者的分享! 原文地址 通过金矿模型介绍动态规划 对于动态规划,每个刚接触的人都需要一段时间来理解,特别是第一次接触的时候总 ...
- python flask (一)
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello World ...
- docker常用命令
yum install wget -y wget -O etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7 ...
- [LeetCode] Design Snake Game 设计贪吃蛇游戏
Design a Snake game that is played on a device with screen size = width x height. Play the game onli ...
- 用Tensorflow让神经网络自动创造音乐
#————————————————————————本文禁止转载,禁止用于各类讲座及ppt中,违者必究————————————————————————# 前几天看到一个有意思的分享,大意是讲如何用Ten ...
- sublimetext3中保存代码片段
在日常的开发工作中,不断重复上一次敲过的代码,有时确实感到伐木累."蓝瘦"(难受)."香菇"(想哭),大概表达的也是这样的心境吧!:grinning: 所以,在 ...
- 【Mysql】 局域网远程连接问题
设置了 user 表 的 host为‘%’ 为什么局域网还是连接不上: 新建查询-->分别执行 1.GRANT ALL PRIVILEGES ON *.* TO'root'@'%' IDENTI ...
- 红米3 TWRP-3.0.3-RECOVERY-7.1.1中文版 20170101更新修复版
1-刷7.1的包不再提示错误命令. 2-基于安卓7.1.1-r6适配. 3-支持屏蔽检验,刷官方包不卡米. 4-禁止恢复RECOVER. 下载地址: https://pan.baidu.com/s/1 ...
- hibernate入门案例
最近准备学ssh,今天学了一下hibernate,用的是hibernate4,现在已经出5了:配置文件很容易写错,写配置文件的时候尽量复制. 需要的jar包如下:(jar包我是直接放在项目工程里面了, ...