黑马程序员技术交流社区
标题:
多线程中的Runnable和Thread 的区别。
[打印本页]
作者:
wangning9130
时间:
2013-9-16 17:31
标题:
多线程中的Runnable和Thread 的区别。
关于多线程有两种方式,这个大家都很清楚。一个是通过实现Runnable接口,另一个是继承Thread类。
通过实现Runnable接口来实现可以避免java单继承的问题。
可是,今天看毕老师视频。其中说到卖票的地方,就有些不明白了。四个窗口一块卖票。一共一百张。
为什么用实现runnable的方式就能实现是个线程一共卖一百张呢?
而另一中就不行呢?
作者:
酱爆
时间:
2013-9-16 17:53
两种都可以实现卖票程序,只是Thread是继承关系,runnable是接口,如果你先前已经继承了一个类,你就不能再继承Thread了(java单继承),所以你可以实现Runnable接口,这要看实际应用吧。。不知道说的对不对
作者:
周文斌
时间:
2013-9-16 18:28
哈哈,同学问的好,我前几天刚写了一篇关于接口的文章,里面就是拿Runnable接口和Thread类做的例子。
http://tdtdtq.blog.163.com/blog/static/2256531472013815119286/?newFollowBlog
下面我来给你讲讲为什么实现Runnable接口能做到四个窗口公卖一百张,而继承Thread类不可以。
class ChildThread extends Thread{
private int count=100;
run(){
System.out.println(count--);
};
}
public class Test{
public static void main(String[] args){
new ChildThread().start();
new ChildThread().start();
new ChildThread().start();
new ChildThread().start();
}
}
复制代码
上面这个例子 就是 用继承Thread类,覆盖了run()方法做的。可以看到,在内存中每个ChildThread对象都有自己的内存空间,当JVM调用run()方法操作count成员时,实际上大家操作的都是自己的count~其实这就是各卖各的票了,为了让四个线程都操作一个count,我们可以将count静态化(当然这不是最优选)。
下面要说的是实现Runnable接口的方式做。
Runnable R=new Runnable(){
run(){
.....
}
}
new Thread( R ).start();
new Thread( R ).start();
new Thread( R ).start();
new Thread( R ).start();
复制代码
大家应该都知道,咱们之前复写Thread类的run()方法是用于给JVM调用的,也就是说Runnable接口方式也是用了某种技巧,让Thread类的run()方法调用到我们在实现Runnable接口时覆盖的run方法!
嗯~下面我们只需要追踪源代码即可。
public class Thread implements Runnable {
...
//定义了一个Runnable的对象
private Runnable target;
...
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
....
//通过构造函数传进来的Runnable对象直接赋值给了成员target。。。
this.target = target;
....
}
public void run() {
if (target != null) {
/[color=Red]/最重要的一点,居然调用的是成员变量中的run方法![/color]
target.run();
}
}
}
复制代码
一目了然了吧~事实上,Thread类中本身有有一个Runnable成员对象,run方法中的代码也就是调用Runnable对象的run,当我们在做new Thread(R)时,已经将Thread类中的Runnable对象指向了R,即四个窗口中的Runnable对象都指向了同一个对象R!
当JVM调用这四个窗口的run方法时,就是同时调用了四次R.run()来操作R.count!那么就实现了四窗口同时卖票了!
你的问题,我想我应该已经解释清楚了。然后再说一个事儿,继承Thread类的方式真的只能通过static count来操作同一个count吗??
第二种方式告诉我们,可以通过往Thread类中传递同一个操作对象(R)就能达到,那么我们能不能用某种方式在第一种情况下也实现呢?
class Tickets{
private int count;
public void Sell(){
System.out.println(count.--);
}
}
class ChildThread{
private Tickets ticket;
ChildThread(Tickets ticket){
this.ticket=ticket;
}
run(){
ticket.Sell();
};
}
public class Test{
public static void main(String[] args){
Tickets t = new Tickets();
new ChildThread(t).start();
new ChildThread(t).start();
new ChildThread(t).start();
new ChildThread(t).start();
}
}
复制代码
你看,这样是不是在单继承的情况也实现了四窗口卖同一组票??哈哈,关键还是大家操作的都是一组票就成啦~~~(这种方式不实战推荐,仅用作比对学习~~^_^~
希望能对你有帮助!(斑斑求多给点儿分呗~~
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2