- 浏览: 432534 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
haoxuexi87:
【学途无忧网】Hive详解 ...
Hive详细配置手册 -
jamin415:
感觉楼主还没理解透彻,可以先看看源代码这两个类是怎么实现的,T ...
Java中继承thread类与实现Runnable接口的区别 -
hudazheng:
mars914 写道a455642158 写道非常感谢……对于 ...
Java中继承thread类与实现Runnable接口的区别 -
coolcgp:
博主用继承Thread用new,用Runnable时用共享,概 ...
Java中继承thread类与实现Runnable接口的区别 -
Koby丶:
flight2006 写道这篇文章举例和结论都没错,但是博主理 ...
Java中继承thread类与实现Runnable接口的区别
Java中线程的创建有两种方式:
1. 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中
2. 通过实现Runnable接口,实例化Thread类
在实际应用中,我们经常用到多线程,如车站的售票系统,车站的各个售票口相当于各个线程。当我们做这个系统的时候可能会想到两种方式来实现,继承Thread类或实现Runnable接口,现在看一下这两种方式实现的两种结果。
package com.threadtest;
class MyThread extends Thread{
private int ticket = 10;
private String name;
public MyThread(String name){
this.name =name;
}
public void run(){
for(int i =0;i<500;i++){
if(this.ticket>0){
System.out.println(this.name+"卖票---->"+(this.ticket--));
}
}
}
}
public class ThreadDemo {
public static void main(String[] args) {
MyThread mt1= new MyThread("一号窗口");
MyThread mt2= new MyThread("二号窗口");
MyThread mt3= new MyThread("三号窗口");
mt1.start();
mt2.start();
mt3.start();
}
}
运行结果如下:
一号窗口卖票---->10 一号窗口卖票---->9 二号窗口卖票---->10 一号窗口卖票---->8 一号窗口卖票---->7 一号窗口卖票---->6 三号窗口卖票---->10 一号窗口卖票---->5 一号窗口卖票---->4 一号窗口卖票---->3 一号窗口卖票---->2 一号窗口卖票---->1 二号窗口卖票---->9 二号窗口卖票---->8 三号窗口卖票---->9 三号窗口卖票---->8 三号窗口卖票---->7 三号窗口卖票---->6 三号窗口卖票---->5 三号窗口卖票---->4 三号窗口卖票---->3 三号窗口卖票---->2 三号窗口卖票---->1 二号窗口卖票---->7 二号窗口卖票---->6 二号窗口卖票---->5 二号窗口卖票---->4 二号窗口卖票---->3 二号窗口卖票---->2 二号窗口卖票---->1
通过实现Runnable接口的代码如下:
package com.threadtest; class MyThread1 implements Runnable{ private int ticket =10; private String name; public void run(){ for(int i =0;i<500;i++){ if(this.ticket>0){ System.out.println(Thread.currentThread().getName()+"卖票---->"+(this.ticket--)); } } } } public class RunnableDemo { public static void main(String[] args) { // TODO Auto-generated method stub //设计三个线程 MyThread1 mt = new MyThread1(); Thread t1 = new Thread(mt,"一号窗口"); Thread t2 = new Thread(mt,"二号窗口"); Thread t3 = new Thread(mt,"三号窗口"); // MyThread1 mt2 = new MyThread1(); // MyThread1 mt3 = new MyThread1(); t1.start(); t2.start(); t3.start(); } }
运行结果如下:
一号窗口卖票---->10 三号窗口卖票---->9 三号窗口卖票---->7 三号窗口卖票---->5 三号窗口卖票---->4 三号窗口卖票---->3 三号窗口卖票---->2 三号窗口卖票---->1 一号窗口卖票---->8 二号窗口卖票---->6
为什么会出现这种结果呐。我们不妨做个比喻,其实刚的程序,
继承Thread类的,我们相当于拿出三件事即三个卖票10张的任务分别分给三个窗口,他们各做各的事各卖各的票各完成各的任务,因为MyThread继承Thread类,所以在new MyThread的时候在创建三个对象的同时创建了三个线程;
实现Runnable的, 相当于是拿出一个卖票10张得任务给三个人去共同完成,new MyThread相当于创建一个任务,然后实例化三个Thread,创建三个线程即安排三个窗口去执行。
用图表示如下:
在我们刚接触的时候可能会迷糊继承Thread类和实现Runnable接口实现多线程,其实在接触后我们会发现这完全是两个不同的实现多线程,一个是多个线程分别完成自己的任务,一个是多个线程共同完成一个任务。
其实在实现一个任务用多个线程来做也可以用继承Thread类来实现只是比较麻烦,一般我们用实现Runnable接口来实现,简洁明了。
大多数情况下,如果只想重写 run() 方法,而不重写其他 Thread 方法,那么应使用 Runnable 接口。这很重要,因为除非程序员打算修改或增强类的基本行为,否则不应为该类(Thread)创建子类。
评论
MyThread1 mt = new MyThread1();
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
我们老大非常反感,说你这样写是错的,跟我说是在api里面找不到根据。
我也不会解释,哎,无语。
jdk api 里面没有说明,但是可以通过程序的执行来说明,事实。
MyThread1 mt = new MyThread1(); 改成 Runnable mt = new MyThread1();
实现Runable的一个好处就是能实现资源共享,结论正确(因为继承Thread实现不了)
但是不是说实现Runable就是实现了资源共享,实际上还是通过
MyThread1 mt = new MyThread1();
这个对象实现的共享,如果是三个不同对象:
MyThread1 mt1 = new MyThread1(); MyThread1 mt2 = new MyThread1(); MyThread1 mt2 = new MyThread1(); Thread t1 = new Thread(mt1,"一号窗口"); Thread t2 = new Thread(mt2,"二号窗口"); Thread t3 = new Thread(mt3,"三号窗口");
这样执行的结果是和上面完全一样的。
总结一下,实现Runable除了避免单继承的局限外,还有个好处就是能实现不同进程资源共享,而继承Thread没有这个功能。并不是这个特点是两者的绝对区别,继承Runable你可以选择不共享。
Thread也能共享资源,
MyThread mt= new MyThread();
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
执行结果和Runnable一样
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
你这种写法存在很大的问题,t1读取ticket=1,因为是多线程t2也可能在读取ticket=1,
t1对ticket-- ,ticket =0 ,此时t2也对ticket--,因为判断还有票,那么此时的ticket=-1
实现Runable的一个好处就是能实现资源共享,结论正确(因为继承Thread实现不了)
但是不是说实现Runable就是实现了资源共享,实际上还是通过
MyThread1 mt = new MyThread1();
这个对象实现的共享,如果是三个不同对象:
MyThread1 mt1 = new MyThread1(); MyThread1 mt2 = new MyThread1(); MyThread1 mt2 = new MyThread1(); Thread t1 = new Thread(mt1,"一号窗口"); Thread t2 = new Thread(mt2,"二号窗口"); Thread t3 = new Thread(mt3,"三号窗口");
这样执行的结果是和上面完全一样的。
总结一下,实现Runable除了避免单继承的局限外,还有个好处就是能实现不同进程资源共享,而继承Thread没有这个功能。并不是这个特点是两者的绝对区别,继承Runable你可以选择不共享。
MyThread1 mt = new MyThread1(); Thread t1 = new Thread(mt,"一号窗口"); Thread t2 = new Thread(mt,"二号窗口"); Thread t3 = new Thread(mt,"三号窗口");
这里代码有问题啊,不是Thread和runnable的问题。。这里共享一个资源了。。
其实就是接口和继承的问题。。
Thread t1 = new Thread(new MyThread1(),"一号窗口"); Thread t2 = new Thread(new MyThread1(),"二号窗口"); Thread t3 = new Thread(new MyThread1(),"三号窗口");
这样才是ok的。每一个线程一个资源
thanks,明白了。楼主自己把自己讲糊涂了,让我也糊涂了。他的结果出现的原因是因为资源共享,与线程的实现方式并无关······大牛,接着帮忙回答下这个问题呗http://bbs.csdn.net/topics/390889930
MyThread1 mt = new MyThread1(); Thread t1 = new Thread(mt,"一号窗口"); Thread t2 = new Thread(mt,"二号窗口"); Thread t3 = new Thread(mt,"三号窗口");
这里代码有问题啊,不是Thread和runnable的问题。。这里共享一个资源了。。
其实就是接口和继承的问题。。
Thread t1 = new Thread(new MyThread1(),"一号窗口"); Thread t2 = new Thread(new MyThread1(),"二号窗口"); Thread t3 = new Thread(new MyThread1(),"三号窗口");
这样才是ok的。每一个线程一个资源
MyThread mt1= new MyThread("一号窗口");
MyThread mt2= new MyThread("二号窗口");
MyThread mt3= new MyThread("三号窗口");
创建了3个MyThread对象,分别执行start()方法,每个对象都有自己的ticket=10
如果private static ticket = 10; 就可以实现拥有共同的ticket=10
执行结果就跟实现Runnable一样了
当实现Runnable的时候
MyThread1 mt = new MyThread1();
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
创建了一个对象,3个进程, 共用一个对象,共同拥有一个ticket=10
这样理解对不对?
MyThread1 mt = new MyThread1();
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
和
MyThread mt1= new MyThread("一号窗口");
MyThread mt2= new MyThread("二号窗口");
MyThread mt3= new MyThread("三号窗口");
mt1.start();
mt2.start();
mt3.start();
两种写法之间的区别,不要上升到Java中继承thread类与实现Runnable接口的区别好不!
问下这两种写法不是正好对应继承thread类与实现Runnable接口吗?哪儿错了吗?只不过实现Runnable接口平常都是创建匿名对象直接调用start()方法吧
MyThread1 mt = new MyThread1();
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
和
MyThread mt1= new MyThread("一号窗口");
MyThread mt2= new MyThread("二号窗口");
MyThread mt3= new MyThread("三号窗口");
mt1.start();
mt2.start();
mt3.start();
两种写法之间的区别,不要上升到Java中继承thread类与实现Runnable接口的区别好不!
MyThread mt2= new MyThread("二号窗口");
MyThread mt3= new MyThread("三号窗口");
由于Thread类本身也实现了Runnable接口,所以上面的写法也可以写成
MyThread mt= new MyThread(); Thread t1 = new Thread(mt,"一号窗口"); Thread t2 = new Thread(mt,"二号窗口"); Thread t3 = new Thread(mt,"三号窗口");
当然这种写法并不好,但足以说明你的想法是错误
对于第二种写法
MyThread1 mt = new MyThread1();
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
可以改成
Thread t1 = new Thread(new MyThread1(),"一号窗口");
Thread t2 = new Thread(new MyThread1(),"二号窗口");
Thread t3 = new Thread(new MyThread1(),"三号窗口");
这两种的区别主要还是接口和继承类的区别
MyThread1 mt = new MyThread1();
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
我们老大非常反感,说你这样写是错的,跟我说是在api里面找不到根据。
我也不会解释,哎,无语。
jdk api 里面没有说明,但是可以通过程序的执行来说明,事实。
谢谢 我在jdk api里面找到这种写法了哈……
MyThread1 mt = new MyThread1();
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
我们老大非常反感,说你这样写是错的,跟我说是在api里面找不到根据。
我也不会解释,哎,无语。
jdk api 里面没有说明,但是可以通过程序的执行来说明,事实。
MyThread1 mt = new MyThread1();
Thread t1 = new Thread(mt,"一号窗口");
Thread t2 = new Thread(mt,"二号窗口");
Thread t3 = new Thread(mt,"三号窗口");
我们老大非常反感,说你这样写是错的,跟我说是在api里面找不到根据。
我也不会解释,哎,无语。
1.适合多个相同程序代码的线程去处理同一资源的情况,把虚拟CPU(线程)同程序的代码、数据有效分离,较好地体现了面向对象的设计思想。
2.可以避免由于JAVA的单继承特性带来的局限。我们经常碰到这样一种情况,即当我们要将已继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么,这个类就只能采用实现Runnable接口的方式了。
3.有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程可以操作相同的数据,与它们的代码无关。当共享访问相同的对象时,即它们共享相同的数据。当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable接口的类的实例。
事实上,几乎所有多线程应用都可以用实现Runnable接口的方式。
//上面所说的看得不是很明白,但大致从两个方面分析了两种实现多线程方法的区别,一就是资源共享,二就是java单继承的问题。
-------------------------------------------------------------------------------------
对于具有相同目标对象的线程,当其中一个线程享用CPU资源时,目标对象自动调用接口中的run()方法,这时run()方法中的局部变量被分配内存空间。当轮到另一个线程享用CPU资源时,目标对象会再次调用接口中的run()方法,那么run()方法中的局部变量会再次分配内存空间。也就是说,run()方法已经启动运行了两次,分别运行在不同的线程中,即运行在不同的时间片内。run()方法中的局部变量称为线程的局部变量。不同线程的run()方法中的局部变量互不干扰,一个线程改变了自己的run()方法中局部变量的值,不会影响其他线程的run()方法中的局部变量。
发表评论
-
java中的String类常量池详解
2012-05-04 16:47 1819String常量池详解: 1.String使用private ... -
Java 集合框架的体系
2012-05-02 20:42 2189一、概述 在Java语言中,Java语言的设计者对常用 ... -
八皇后算法详解
2012-03-15 18:14 26411.引子 中国有一句 ... -
java.lang.OutOfMemoryError异常解决方法
2012-03-08 14:52 29436原因:常见的有以下几种: 1.内存中加载的数据量过于庞大,如 ... -
String\StringBuilder\StringBuffer之间的区别
2012-03-04 21:11 68741、String类 String 本身的值是不能改变的 ... -
抽象类和接口的区别
2012-03-04 14:14 1241一、abstract 类 如果一个类中没有包含足够的信息来 ... -
Java基本数据类型
2012-02-06 19:20 1397基本类型,或者叫做内置类型,是JAVA中不同于类的特殊类型。它 ... -
Java的SPI机制
2011-11-29 13:34 3512SPI的全名为Service Provider Int ...
相关推荐
Java 中继承 Thread 类与实现 Runnable 接口的比较 在 Java 中,创建线程有两种方式:继承 Thread 类和实现 Runnable 接口。这些方式都可以用来创建线程,但它们之间有着一些关键的区别。 继承 Thread 类 继承 ...
Java提供了两种主要的方式来创建线程:继承Thread类和实现Runnable接口。本篇文章将深入探讨通过实现Runnable接口来创建线程的方法,以及这种方式相比于直接继承Thread类的优势。 首先,我们来看Runnable接口。在...
在Java编程语言中,创建线程有两种主要方式:继承`Thread`类和实现`Runnable`接口。由于Java的单继承特性,当一个类需要继承其他类时,就不能再直接继承`Thread`,这时实现`Runnable`接口就成为创建线程的优选方案。...
在Java编程语言中,多线程的实现有多种方式,其中最常见的是通过继承`Thread`类和实现`Runnable`接口。这两种方法各有其特点和适用场景,理解它们之间的区别对于编写高效、可维护的多线程应用至关重要。 ### 继承...
这两种方法都可以实现阶乘计算的多线程化,主要区别在于继承`Thread`时,线程行为直接与类绑定,而实现`Runnable`接口时,线程行为是通过对象实例传递的。选择哪种方式取决于具体需求和设计考虑,例如是否需要复用类...
在Java编程语言中,创建多线程有两种主要的方法:继承`Thread`类和实现`Runnable`接口。这两种方法都是为了使程序能够同时执行多个任务,从而提高效率和响应性。 **1. 继承Thread类** 当一个类直接继承自`Thread`类...
**二、继承Thread类** 1. 创建一个继承`Thread`的类,如`RandomSquareThread`,并重写`run()`方法。 ```java public class RandomSquareThread extends Thread { @Override public void run() { // 实现画随机...
如果希望保持类的独立性,或者需要与其他类共享数据,推荐实现`Runnable`接口。 总结,实现`Runnable`接口是创建Java多线程的一种常见方式,它提供了更大的灵活性,尤其是在需要多继承或者线程之间需要共享数据的...
1. 写两个线程,一个线程打印1-52,另一个线程打印字母A-Z。打印顺序为12A34B56C……5152Z。 学习线程之间的通信协调关系。 2. 使用 runnable 接口实现按两... 使用继承Thread类方式和实现Runnable接口两种方式实现。
在Java中,实现多线程的两种主要方式分别是:**通过继承`Thread`类** 和 **实现`Runnable`接口**。下面将详细介绍这两种方式,并提供相应的示例程序。 #### 一、通过继承`Thread`类实现多线程 在Java中,可以通过...
在Java中,线程可以通过Thread类或Runnable接口来实现。 Runnable接口是Java.lang包中的一部分,它定义了一个run()方法,该方法将被线程执行。Runnable接口的特点包括: * 只有一个run()方法 * 需要创建一个Thread...
同样,你需要重写`run()`方法,但这次是在实现接口的类中: ```java public class MyRunnable implements Runnable { @Override public void run() { // 线程执行的代码 } } ``` 然后,将`Runnable`实例传递给...
1. **继承Thread类** - **步骤**: 1. 定义一个类继承自`Thread`。 2. 重写`run()`方法,编写线程体代码。 3. 创建该类的实例,并调用`start()`方法启动线程。 - **示例代码**: ```java class MyThread ...
Java提供了两种创建线程的方式:继承Thread类和实现Runnable接口。 1. 继承Thread类创建线程: 当你选择继承Thread类时,你需要创建一个新的类,这个类扩展自Thread类。Thread类已经实现了Runnable接口,所以你不...
2.1 继承Thread类 2.2 实现Runnable接口 3. 实现Runnable接口: 3.1 实现步骤 3.2 优点与用途 4. 启动线程: 4.1 使用Thread类启动线程 4.2 使用Executor框架启动线程池 5. 传递参数给线程: 5.1 使用构造方法传递...
Runnable接口的实现可以独立执行,不需要继承Thread类。Runnable接口的实现可以通过Thread类来执行。 Thread类和Runnable接口的主要区别在于继承性。Thread类是Java中的一个类,它不能被继承,而Runnable接口是一个...
在 Java 中,实现多线程有两种方法:继承 Thread 类和实现 Runnable 接口。在本文中,我们将对这两种方法进行详细的介绍和对比。 继承 Thread 类 继承 Thread 类是 Java 中最基本的多线程实现方法。 Thread 类提供...
Java 中创建线程通常有两种方式:继承 Thread 类和实现 Runnable 接口。虽然继承 Thread 类可以创建线程,但是在实际开发中,更常用的是实现 Runnable 接口。为什么呢?这是因为 Java 中一个类可以实现多个接口,但...
### 多线程的Runnable与Thread的区别 在Java中实现多线程有两种主要方式:一种是继承`Thread`类;另一种是实现`Runnable`接口。本文将深入探讨这两种方法的区别,帮助初学者更好地理解并选择适合场景的多线程实现...
- **好处**:Java中的`Runnable`接口允许我们将线程逻辑(run()方法)封装在不直接继承自`Thread`类的类中。这样做的好处是可以避免单继承的限制,因为Java不支持多继承。同时,由于实现了Runnable接口的类还可以...