黑马程序员技术交流社区
标题:
关于怎么实现多线程
[打印本页]
作者:
于振发
时间:
2013-9-26 01:53
标题:
关于怎么实现多线程
我知道java创建线程类的两中方式,一种是继承Thread类,一种是实现Runnable接口。
我想问的是在实际开发中,用那种方式好一些呢?
他们有什么区别呢?
有的人说使用第二种好,就是实现Runnable接口,这样推荐,只是为了避免java的单继承吗?
这两种方式在底层的实现有什么不同?
作者:
咕咕猫
时间:
2013-9-26 07:46
实现方式的好处:避免了单继承的局限性,在定义线程时,建议使用实现方式。
区别在于:继承Thread,线程代码存放在Thread子类run方法中 实现Runnable,线程代码存在接口的子类run方法中。
创建多条操作共享数据的时要用实现Runnable接口方式,只是建立单线程的话要求就没那么多了。
作者:
hoyouly
时间:
2013-9-26 08:37
实现方式和继承方式怎么选择:建议使用实现方式,因为首先看API会发现,其实Thread类也实现了Runnable接口的,也就是说,Thread类中的run方法时实现的Runnable接口的run方法的,从某种意义上说,Runnable是Thread类的爹,我们是可以通过继承Thread类来实现多线程,那样我们就是Runnable接口的孙子辈了,而如果我们直接实现Runnable接口,那么就是Runnable接口的儿子。既然能当儿子,何必装孙子呢,是吧,为什么我们不直接去实现Runnable接口呢,就像毕老师说的那样:要穿一手鞋,能不穿二手甚至多手鞋就不穿。可能这个例子有点不恰当。但是从另一个java语法上看待这个问题,也是建议使用实现方式,而不是继承方式,因为如果一个类要想通过继承Thread类创建线程,那么这样的话,他就不能去继承其他的类了,java类中只能单继承,不能进行多继承。而要是通过实现Runnable接口的方式的话,就可以即继承父类,实现其他的接口,java中一个类可以实现多个接口。
实现方式好处:避免了单继承的局限性。故在定义线程时,建立使用实现方式。
继承Thread, 线程代码存放Thread子类run方法中。
实现Runnable,线程代码存在接口的子类的run方法。
这是我自己的一些理解,希望对你有用
作者:
杨修
时间:
2013-9-26 09:08
建议你对比一下售票的例子,其中从继承Thread到Runnable是怎么过度的,就知道Runnable的好处了。
另外,其他区别楼上都说了。
作者:
wrswuxiaoyan
时间:
2013-9-26 09:41
我来分享下,我昨天一个总结,从thread到Runnable!
举例来说明吧,这样更志直观些
以火车票同时开4个窗口进行卖票为例:
但是运行的结果是这样的,请看下边截图
第一张票同时被第2个线程和第3个线程同时应用,在现实生活是不存在的啊,你想想同样的火车票不可能同时的卖给两个人吧!
第一张票同时被第2个线程和第3个线程同时应用,在现实生活是不存在的啊,你想想同样的火车票不可能同时的卖给两个人吧!
思考下这个问题怎么解决呢?
出现的原因:
出现这个问题的原因是,在main主方法中同时new出四个单线程的对象,当线程开启的时候,每个线程都会去调用一次run方法,每次调用的ticket变量都是100,都是从100循环开始的,这导致一张票同时卖给两个人的现象。
解决办法:
1、只要让int ticket=100称为一个静态的变量就可以了,但是,静态变量的生命周期太长,所以不建议用这种方法。
2、public static void main(String[] args)
{
mythread tic1=new mythread();
mythread tic2=new mythread();
mythread tic3=new mythread();
mythread tic4=new mythread();
tic1.start();
tic2.start();
tic3.start();
tic4.start();
}
在main主方法中一共new了四个不同的对象,在内存中就有了4个不同的空间,现在想办法让四个线程去共用一个对象,就可以解决这种情况了!怎么样实现呢,新的东西又引进了,咱们可以不继承Thread类,而去实现Runnable的接口,在main方法中
public static void main(String[] args)
{
mythread tic1=new mythread();
Thread t1=new Thread(tic1);
Thread t2=new Thread(tic1);
Thread t3=new Thread(tic1);
Thread t4=new Thread(tic1);
t1.start();
t2.start();
t3.start();
t4.start();
}
new出tic1对象,把这个对象全部给了new出的四个线程中,这样他们四个线程就共享了同一个tic1对象,
class mythread implements Runnable
{
public static int ticket=100;
public void run()
{
while(true)
{
if(ticket>0)
{
System.out.println(Thread.currentThread().getName()+"....."+ticket--);
}
}
}
}
最后总的代码是这样的
class mythread implements Runnable
{
public static int ticket=100;
public void run()
{
while(true)
{
if(ticket>0)
{
System.out.println(Thread.currentThread().getName()+"....."+ticket--);
}
}
}
}
class threadDemo
{
public static void main(String[] args)
{
mythread tic1=new mythread();
Thread t1=new Thread(tic1);
Thread t2=new Thread(tic1);
Thread t3=new Thread(tic1);
Thread t4=new Thread(tic1);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
作者:
wrswuxiaoyan
时间:
2013-9-26 09:48
上边第一个图片不显示,我这里把代码复制下class mythread extends Thread
{
public int ticket=100;
public void run()
{
while(true)
{
if(ticket>0)
{
System.out.println(Thread.currentThread().getName()+"....."+ticket--);
}
}
}
}
class threadDemo
{
public static void main(String[] args)
{
mythread tic1=new mythread();
mythread tic2=new mythread();
mythread tic3=new mythread();
mythread tic4=new mythread();
tic1.start();
tic2.start();
tic3.start();
tic4.start();
}
}
以上我是举例说明的从Thread到Runnable接口的应用过程
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2