黑马程序员技术交流社区

标题: 多线程两创建方式的问题 [打印本页]

作者: 罗雪梅    时间: 2012-9-30 10:34
标题: 多线程两创建方式的问题
本帖最后由 罗雪梅 于 2012-9-30 17:09 编辑

第一种方式创建:直接继承Thread类,重写里面的run()方法,启动线程
//创建一个已经继承了Thread类的子类对象
ProductThread   pt=new ProductThread();
//启动线程
pt.start();

第二种方式创建:先让本类去实现Runnable接口,重写run()方法,创建Thread类的线程对象,将实现了Runnable接口的子类对象做为参数传给Thread类的构造方法,调用Thread类的Start()方法。
//实现Runnable接口的本类对象的创建
Product    p=new Product();
//创建一个线程对象,把p传给他
Thread   t=new  Thread(p);
//启动线程
t.start();



老师说第二种方式更好,a)        Runnbale接口的出现,避免了单继承的局限性。
                               b)       将线程运行的代码都单独封装到Runnable接口类型的对象中,这样就实现了线程对象和任务对象的解耦(降低耦合性).

b)我明白能理解他的好处,但a)呢,接口是可以多实现,不过我创建线程只是继承一个Thread类啊,不用在继承其它的了与这个局限性好像关系不太大,而且第一种方式代码更少啊

作者: 谭立文    时间: 2012-9-30 10:52
可能你写的这个类要实现的功能比较少,可能只是一个简单的演示效果,而真正在项目当中很多都是需要实现多个接口或基于某个类之后在写的,其实在线程的创建的两种方式,有一个原则,能用实现Runnable接口就不要继承。
作者: 尤洋    时间: 2012-9-30 10:55
你这只是在特定的情况下:
而开发中更可能出现的情况是 你不知道 想实现多线程的那个类到底是不是已经有一个父类了
或者是 该类已经有一个其他的父类了,但你还继续想要实现多线程。
这时候就必须要用 实现runnable的方式了

另外 两种方法的本质是一样的。因为thread 类 本身就实现了runnable接口
内部调用 run方法的方式 都是  new Runnable(){}.run();l利用匿名内部类 new 父类或接口名 调用子类方法。
作者: 创出一片辉煌    时间: 2012-9-30 12:02
这是Thread实现说车售票的代码
class MyThread1 extends Thread{        // 继承Thread类,作为线程的实现类
        private int ticket = 5 ;                // 表示一共有5张票
        public void run(){        // 覆写run()方法,作为线程 的操作主体
                for(int i=0;i<100;i++){
                        if(this.ticket>0){
                                System.out.println("卖票:ticket = " + ticket--) ;
                        }
                }
        }
};
public class ThreadDemo04{
        public static void main(String args[]){
                MyThread1 mt1 = new MyThread1() ;         // 实例化对象
                MyThread1 mt2 = new MyThread1() ;         // 实例化对象
                MyThread1 mt3 = new MyThread1() ;         // 实例化对象
                mt1.start() ;        // 调用线程主体
                mt2.start() ;        // 调用线程主体
                mt3.start();        // 调用线程主体
        }
};
结果
卖票:ticket = 5
卖票:ticket = 5
卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 4
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 3
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 2
卖票:ticket = 2
卖票:ticket = 1
卖票:ticket = 1
卖票:ticket = 1
这是Runnable实现火车售票代码
class MyThread implements Runnable{        // 继承Thread类,作为线程的实现类
        private int ticket = 5 ;                // 表示一共有5张票
        public void run(){        // 覆写run()方法,作为线程 的操作主体
                for(int i=0;i<100;i++){
                        if(this.ticket>0){
                                System.out.println("卖票:ticket = " + ticket--) ;
                        }
                }
        }
};
public class RunnableDemo02{
        public static void main(String args[]){
                MyThread mt = new MyThread() ;         // 实例化对象
                new Thread(mt).start() ;        // 调用线程主体
                new Thread(mt).start();        // 调用线程主体
                new Thread(mt).start();        // 调用线程主体
        }
};
结果
卖票:ticket = 5
卖票:ticket = 4
卖票:ticket = 3
卖票:ticket = 2
卖票:ticket = 1
总结来说,使用Thread类操作多线程的时候无法达到资源共享的目的,而Runnable操作多线程的时候可以达到资源共享
作者: 罗雪梅    时间: 2012-9-30 17:09
屈俊材 发表于 2012-9-30 12:02
这是Thread实现说车售票的代码
class MyThread1 extends Thread{        // 继承Thread类,作为线程的实现类
        priv ...

奥,还有这个作用,谢谢




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2