多线程之Tread类和Runnable的区别
一.run()方法和start()方法的区别
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。
下面看例子:
package org.thread.demo;
public 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 ThreadRunDemo {
public static void main(String[] args) {
MyThread mt1=new MyThread("线程a");
MyThread mt2=new MyThread("线程b");
mt1.run();
mt2.run();
}
}
console:

结果是按顺序运行,先第一个对象执行,然后第二个对象执行。
在JDK的文档中可以发现,一旦调用start()方法,则会通过JVM找到run()方法。下面启动start()方法启动线程:
package org.thread.demo;
public class ThreadStartDemo {
public static void main(String[] args) {
MyThread mt1=new MyThread("线程a");
MyThread mt2=new MyThread("线程b");
mt1.start();
mt2.start();
}
}
console:

这样程序可以正常完成交互式运行。那么为啥非要使用start();方法启动多线程呢?
在JDK的安装路径下,src.zip是全部的java源程序,通过此代码找到Thread中的start()方法的定义,可以发现此方法中使用了private native void start0();其中native关键字表示可以调用操作系统的底层函数,那么这样的技术成为JNI技术(java Native Interface)
综上,可以得出:
start() 方法的作用是启动一个新线程,新线程会执行相应的run()方法。 而run()方法则只是普通的方法调用,在调用线程中顺序运行而已。
二.Runnable接口
在实际开发中一个多线程的操作很少使用Thread类,而是通过Runnable接口完成。
public interface Runnable{
public void run();
}
例子:
package org.runnable.demo;
package org.thread.demo; public class MyThreadImpRunnable implements Runnable { private String name;
public MyThreadImpRunnable(String name) {
this.name = name;
} @Override
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.thread.demo;
public class RunnableDemo {
public static void main(String[] args) {
MyThreadImpRunnable mt1=new MyThreadImpRunnable("线程a");
MyThreadImpRunnable mt2=new MyThreadImpRunnable("线程b");
new Thread(mt1).start();
new Thread(mt2).start();
}
}
console:

两种实现方式的区别和联系:
在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下好处:
避免点继承的局限,一个类可以继承多个接口; 实现资源的共享
以卖票程序为例,通过Thread类完成:
package org.thread.demo;
public class MyTheard02 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.thread.demo;
public class ThreadTicket{
public static void main(String[] args) {
MyThread02 mt1=new MyThread02();
MyThread02 mt2=new MyThread02();
MyThread02 mt3=new MyThread02();
mt1.start();//每个线程都各卖了10张,共卖了30张票
mt2.start();//但实际只有10张票,每个线程都卖自己的票
mt3.start();//没有达到资源共享
}
}
console:

每个线程都各卖了10张,共卖了30张票,但实际只有10张票,每个线程都卖自己的票,没有达到资源共享
如果用Runnable就可以实现资源共享,下面看例子:
package org.thread.demo;
public class MyThread02ImpRunnable implements Runnable {
private int ticket=10;
@Override
public void run() {
for(int i=0;i<20;i++){
if(this.ticket>0){
System.out.println("通过实现runnable接口卖票:ticket"+this.ticket--);
}
}
}
}
package org.thread.demo;
public class RunnableTicket {
public static void main(String[] args) {
MyThread02ImpRunnable mt=new MyThread02ImpRunnable();
new Thread(mt).start();//同一个mt,但是在Thread中就不可以,如果用同一
new Thread(mt).start();//个实例化对象mt,就会出现异常
new Thread(mt).start();
}
}
console:

虽然现在程序中有三个线程,但是一共卖了10张票,也就是说使用Runnable实现多线程可以达到资源共享目的。
多线程之Tread类和Runnable的区别的更多相关文章
- Java基础-进程与线程之Thread类详解
Java基础-进程与线程之Thread类详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.进程与线程的区别 简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程 ...
- java多线程之yield,join,wait,sleep的区别
Java多线程之yield,join,wait,sleep的区别 Java多线程中,经常会遇到yield,join,wait和sleep方法.容易混淆他们的功能及作用.自己仔细研究了下,他们主要的区别 ...
- 多线程之ThreadLocal类
深入研究java.lang.ThreadLocal类 0.前言 ThreadLocal(线程变量副本)Synchronized实现内存共享,ThreadLocal为每个线程维护一个本地变量.采用空间换 ...
- Java多线程之Callable接口与Runnable的实现以及选择
通过实现Runnable接口的实现 package Thread; import java.util.concurrent.ExecutorService;import java.util.concu ...
- 多线程之Thread类
Java并发编程:Thread类的使用 在前面2篇文章分别讲到了线程和进程的由来.以及如何在Java中怎么创建线程和进程.今天我们来学习一下Thread类,在学习Thread类之前,先介绍与线程相关知 ...
- JUC多线程之ThreadPoolExecutor类任务执行流程
ThreadPoolExecutor类: ThreadPoolExecutor是我们最常用的一个线程池类,它实现了AbstractExecutorService接口.首先来看一下它的构造器及相关关键变 ...
- 多线程之Parallel类
Parallel类是对线程的一个抽象.该类位于System.Threading.Tasks名称空间中,提供了数据和任务并行性. Paraller类定义了数据并行地For和ForEach的静态方法,以及 ...
- C# 多线程之Thread类
使用System.Threading.Thread类可以创建和控制线程. 常用的构造函数有: // 摘要: // 初始化 System.Threading.Thread 类的新实例,指定允许对象在 ...
- 多线程之:lock和synchronized的区别
多次思考过这个问题,都没有形成理论,今天有时间了,我把他总结出来,希望对大家有所帮助 1.ReentrantLock 拥有Synchronized相同的并发性和内存语义,此外还多了 锁投票,定时锁等候 ...
随机推荐
- 洛谷 P1484 种树 题解
题面 这是一道标准的带反悔贪心: 利用大根堆来维护最大值: 当选择了num[i]后,反悔了,反之选择选了num[i-1]和num[i+1]时获利便增加了num[i-1]+num[i+1]-num[i] ...
- laravel修改用户模块的密码验证
做项目的时候,用户认证几乎是必不可少的,如果我们的项目由于一些原因不得不使用 users 之外的用户表进行认证,那么就需要多做一点工作来完成这个功能. 现在假设我们只需要修改登录用户的表,表名和表结构 ...
- linux 内核数据结构之红黑树.
转载: http://www.cnblogs.com/haippy/archive/2012/09/02/2668099.html https://zh.wikipedia.org/zh/%E7%BA ...
- 均值滤波器(平滑空间滤波器)基本原理及Python实现
1. 基本原理 使用元素的领域内像素的平均值代替该元素,可明显的降低图像灰度的尖锐变换.它的一种重要应用是模糊处理:得到感兴趣的区域的粗略表示,将次要的/小的元素与背景融合,使得主要的/较大的元素变得 ...
- 【iOS】正則表達式抓取网页数据制作小词典
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/xn4545945/article/details/37684127 应用程序不一定要自己去提供数据. ...
- Laravel - 验证码(captcha)
首先,登录网址 packagist.org 查找 laravel captcha,找到mews/captcha ,根据 packagist 上的使用方法一步步来实现验证码的安装.配置composer. ...
- (转) Windows下MySQL免安装版的下载与配置
本人在尊重原著的前提下.针对在实践中所遇到的问题加以整理和完善,如有不足之处,还请各位大神指点江山O(∩_∩)O~ 主要是因为平时自己学习时候会用到.及免安装版本的方便.对于个人开发者挺实用的! 安装 ...
- Jsoup抓取网页数据完成一个简易的Android新闻APP
前言:作为一个篮球迷,每天必刷NBA新闻.用了那么多新闻APP,就想自己能不能也做个简易的新闻APP.于是便使用Jsoup抓取了虎扑NBA新闻的数据,完成了一个简易的新闻APP.虽然没什么技术含量,但 ...
- MySQL Select查询
1. 基本语法: SELECT {* | <字段列名>} [ FROM <表 1>, <表 2>… [WHERE <表达式> [GROUP BY < ...
- node.js 实现 AES CTR 加解密
node.js 实现 AES CTR 加解密 node aesctr 前言 由于最近我们在做一款安全的文件分享 App, 所有文件均需要使用 aes ctr 来进行加密,aes key 还有一整套完整 ...