A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 王俊杰 中级黑马   /  2013-3-9 21:08  /  1518 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 王俊杰 于 2013-3-12 22:16 编辑


请问在实现Runnable的类里面添加Thread类型的成员变量有神马好处啊?


我重新编辑了一下,我想尽量把问题说清楚。原谅我的语无伦次。要是您觉得说的比较乱,就凑合着看吧 哈哈
我在学习线程的时候学会了两种基本的线程实现方式。其中一种是实现Runnable接口。
把实现Runnable接口的对象作为参数,再由Thread的构造方法构造成为一个线程。
我也是习惯了这样做的。

可是我前几天看到一种新的方法。
一个实现了Runnable接口的类中添加了一个Thread类型的成员变量。这让我感到很惊奇,可能是我少见多怪吧,感觉太奇妙 了,原来也可以这样做啊。

然后我自己写了两段代码,都i是放在主方法中的。我在想这两种方式有什么区别呢。那种更好一些呢。我觉得,把Thread类的对象作为成员放到实现Runnable的类中,好像更容易理解一些。一个对象内部包含一个线程。而如果用线程来包装这个类,这个线程还要再取个名字。类太多了,类的名字很难让人联想到它本身是个什么东西。这是我的不靠谱的一点想法。
有没有人是这样做的啊?就是在实现Runnable的类里面添加Thread类型的成员变量?能不能告诉我为什么要这样,有神马好处啊?
下面是我写的代码。本来我想用这个代码工具插入来着,感觉不好用,可能我不太会用吧。只好直接贴下面吧。

public static void main(String[] args) {
// 我写成了匿名类。都写在主方法里的。
// 第一种方式:接收一个Runnable对象来构造线程
new Thread(new Runnable() {

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("AAA");
            try {
                Thread.sleep(2000);
            }catch(InterruptedException e) {
            }
         }
     }
}).start();

// 第二种方式:将Thread对象作为Runnable对象的成员
new Runnable() {
    ThreadinnerThread= newThread(this);
    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("BBB");
            try {
                Thread.sleep(2000);
             }catch(InterruptedException e) {
             }
         }
     }

}.innerThread.start();

}



评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1 5分以下,鼓励一下~

查看全部评分

6 个回复

倒序浏览
创建线程有两种方式:
创建新线程第一种方式:继承Thread
步骤:
1、定义类继承Thread;
2、重写Thread 类的 run()方法;
    目的:将自定义的代码存储在run()方法中,让线程运行。
3、调用线程 start() 方法:该方法两个作用:启动线程;调用run()方法;
  1. public class ThreadDemo {
  2.         public static void main(String[] args) {
  3.                 Demo d = new Demo();    //创建一个线程
  4.                 d.start();               //start()方法,启动线程并执行该线程的run()方法
  5.         d.run();                //仅仅是对象调用,线程创建了,但是并没有运行
  6.                 for(int i = 0; i < 50; i++)
  7.                 System.out.println("Hello World--" + i);
  8.         }
  9. }

  10. class Demo extends Thread {
  11.         public void run() {
  12.                 for(int i = 0; i < 50; i++)
  13.                 System.out.println("Demo Run --" + i);
  14.         }
  15. }
复制代码
创建线程的第二种方式:实习Runable接口
步骤:
1、  定义类实现Runable 接口
2、  覆盖Runable接口中的run()方法
        将线程要运行的代码存放在run()方法中。
3、  通过Thread类建立线程对象
4、  将Runable接口的子类对象作为实际参数传递给Tread类的构造函数
   为什么要将Runable接口的子类对象传递给Thread的构造函数。
   因为自定义的run()方法所属的对象是Runable接口的子类对象
   所以要让线程去调用指定对象的run()方法,就必须明确该run()方法所属对象。
5、  调用Thread类的start()方法开启并调用Ruanable接口子类的run()方法;
这一种方式的使用,想必大家都经常使用,就不列举代码了
关于这两种方式的区别:
   继承Thread :线程代码存放在Thread子类run()方法;   实现Runable,线程代码存放在接口的子类run()方法中。

楼主所见到的就是第一种方式,只是并没有继承Thread类,只是直接创建了Thread类的实例对象来开启线程

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1 虽然没完全回答楼主的问题,但非常详细。.

查看全部评分

回复 使用道具 举报
赵彦辉 发表于 2013-3-9 21:35
创建线程有两种方式:
创建新线程第一种方式:继承Thread 类步骤:1、定义类继承Thread;2、重写Thread 类 ...

可能我没有表达清楚。那两段代码是我写的。都是匿名的类。
我所说的两种方式就是那两段代码。你的回答很详细,还是很感谢你。
回复 使用道具 举报
我的表达有些混乱 对不住啦 只看代码部分就好了 我用了匿名的类是想减少不必要的麻烦,重点在构建线程的方式上
正常的方式是二楼说的 “将Runable接口的子类对象作为实际参数传递给Tread类的构造函数”
我见到的还有一种就是在实现Runnable接口的类中增加一个Thread对象作为成员变量,然后通过对象加点,访问这个成员,然后开启线程
回复 使用道具 举报
真不出有什么好处,但坏处很明显,代码变复杂不直观;不仔细看还以为这种代码无法执行
回复 使用道具 举报
描述太混乱了,重点不太突出啊,帮你把问题拿到第一行了,希望有所帮助吧~ 以后发帖只问最关键的就行了,什么自己如何发现的问题啊之类,可以省略的。
回复 使用道具 举报
张宁 中级黑马 2013-3-10 23:34:39
7#
一楼回答得很好,我再补充一下他们的区别吧。
   在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。
   在实际开发中一个多线程的操作很少使用Thread类,而是通过Runnable接口完成。但是在使用Runnable定义的子类中没有start()方法,只有Thread类中才有。此时观察Thread类,有一个构造方法:public Thread(Runnable targer)此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程。(start()可以协调系统的资源):
   两种实现方式的区别和联系:

  在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比
  继承Thread类有如下好处:
  ->避免点继承的局限,一个类可以继承多个接口。
  ->适合于资源的共享
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马