黑马程序员技术交流社区
标题: 关于java中多线程的几种方法 [打印本页]
作者: 陈欢 时间: 2012-7-17 21:04
标题: 关于java中多线程的几种方法
本帖最后由 陈欢 于 2012-7-20 00:39 编辑
关于java中多线程的几种方法
1.java线程中可以实现Runnable借口或者继承Thread类实现,实际中应该怎么样使用呢,还是没怎么理解?(哪位高人有没有详细代码解释一下呢)
作者: 梁小波 时间: 2012-7-17 21:40
建议:把代码弄到代码块上!
你的意思是怎么在main中读取bk1中的private变量吧;
很抱歉不可以!其实非要那么做就用暴力反射,我想那也不是你的意愿!
为什么不可以呢?序列号可以说是为了让对象长久存储!多用在游戏编程,流行的云计算等技术基础!
序列化不会破坏java的规则!所以以前在main中不可以访问private变量;现在也不可以!
那么Book bk1=(Book)oi.readObject();就好比book bk1=new book();
利用bk1能做的和以前一样!
序列化的目的是是为了本地化存储对象,可能现在demo中不是太能体现价值。
作者: 梁小波 时间: 2012-7-17 21:48
为什么在另一个帖中出现了我的上一个贴的答案呢?求解释?
关于这个贴中的问题:到底是继承Thread还是runnable接口?
看实际情况:但通常会实现runnable接口.因为这样你还可以另外继承一个类,
毕竟一个类只能继承一个类,如果继承了thread,就会不能继承其他的了;
而且很多人也是这么做的。
作者: 陈欢 时间: 2012-7-17 21:54
可能有点小巧合吧,我要是明白就去回帖了
作者: 蒋映辉 时间: 2012-7-17 21:58
其实很简单 c++中一个子类可以继承多个父类 但是java中只能继承一个父类,也就是说名额有限,你要是用来继承了Thread类了 就不能继承其他的类了,在实际开发中往往都要继承其他的类的,所以就用事先runnable接口了
作者: 陈欢 时间: 2012-7-17 22:00
哦,看过你们的解释,我基本上明白了,多谢
作者: 陈欢 时间: 2012-7-17 22:02
哦,看过你们的解释我基本上都明白了,多谢
作者: 徐帅 时间: 2012-7-17 22:08
本帖最后由 徐帅 于 2012-7-17 22:09 编辑
其实第一种方法具有局限性,所以大多数使用第二种方式,关于两种方式,总结如下:
创建线程的第一种方式:继承Thread类。
步骤:
1> 定义类继承Thread。
2> 复写Thread类中的run方法。
目的:将自定义代码存储在run方法。让线程运行。
3> 调用线程的start方法,
该方法两个作用:启动线程,调用run方法。
第二种方式:实现Runnable接口
由来:如果自定义的类中有多线程要运行的代码。但是该类有自己的父类。
那么就不可以再继承Thread,因为java中不支持多继承。
步骤:
1>定义类实现Runnable接口
2>覆盖Runnable接口中的run方法。将线程要运行的代码存放在该run方法中。
3>通过Thread类建立线程对象。
4>将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。
5>调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。
2 实现方式和继承方式的区别
1>实现方式好处:避免了单继承的局限性。
在定义线程时,建立使用实现方式。
2> 继承Thread:线程代码存放Thread子类run方法中。
实现Runnable,线程代码存在接口的子类的run方法。
作者: 陈欢 时间: 2012-7-17 22:15
徐帅 发表于 2012-7-17 22:08
其实第一种方法具有局限性,所以大多数使用第二种方式,关于两种方式,总结如下:
创建线程的第一种方式: ...
你写的太清楚,这样理解的更深刻了,厉害,多谢
作者: 徐帅 时间: 2012-7-17 22:17
陈欢 发表于 2012-7-17 22:15
你写的太清楚,这样理解的更深刻了,厉害,多谢
呵呵,都是从视频上总结出来的,一起加油
作者: 柯玲 时间: 2012-7-17 22:25
还是举老师的例子:假设有10张票,需要两个窗口卖(即两个线程),继承Thread类的写法如下:- public class ThreadDemo {
- public static void main(String[] args) {
- Ticket1 t1=new Ticket1();
- Ticket1 t2=new Ticket1();
- t1.start();
- t2.start();
- }
- }
- class Ticket1 extends Thread{
- private int ticket=10;
- public void run(){
- while(true){
- if(ticket>0){
- System.out.println("继承Thread类:"+Thread.currentThread().getName()+"---sales:"+ticket--);
- }
- }
- }
- }
复制代码 实现Runnable接口的方式如下:- public class ThreadDemo {
- public static void main(String[] args) {
- Ticket2 t=new Ticket2();
- new Thread(t).start();
- new Thread(t).start();
- }
- }
- class Ticket2 implements Runnable{
- private int ticket=10;
- public void run(){
- while(true){
- if(ticket>0){
- System.out.println("实现Runnable接口:"+Thread.currentThread().getName()+"---sales:"+ticket--);
- }
- }
- }
- }
复制代码 他们运行打印结果分别为:
从打印结果可以看到:如果是多线程当继承Thread时,每个窗口都会卖掉10张票,造成卖票系统出错
而实现Runnable,就达成了数据的共享,不管有多少个窗口,卖完10张票就没有了,所以为了多线程的安全性最好实现Runnable接口
第二个原因就是,类可以实现多个接口却不可以继承多个父类
-
QQ截图20120717221213.jpg
(63.07 KB, 下载次数: 20)
-
QQ截图20120717221104.jpg
(37.74 KB, 下载次数: 31)
作者: 陈少文 时间: 2012-7-18 09:09
一般情况下,用Runnable接口
一是看起来好看,二,java是不能
多继承的。用Runnable接口后,还可以继承其它类
不过最后还得调用Thread 类
实现Runnable接口
Runnable接口中只定义了一个抽象方法
public void run();
格式:
class 类名称 implement Runnable //实现Runnable接口
{
属性... //类中定义属性
方法... //类中定义方法
public void run() //覆写Runnable接口中的run()方法
{
线程主体;
}
}
例:
class MyThread implements Runnable //实现Runnable接口
{
private String name; //在类中定义一个属性
public MyThread(String name) //定义一个构造方法
{
this.name = name;
}
public void run() //覆写Runnable接口中的run()方法
{
for(int i = 0;i<10;i++)
{
System.out.println(name +"运行"+i)
}
}
}
public class RunnableDemo
{
public static void main(String[] args)
{
MyThread my1 = new Mythread("线程A"); //实例化Runnable子类对象
MyThread my2 = new Mythread("线程B");
/*
要想启用一个多线程必须要使用start()方法完成,如果继承了
Thread类,可以直接使用用start()方法,但是现在实现了
Runnable接口,在Thread中提供了public Thread(Runnabel target)构造方法
就依靠此点来启动线程
*/
Thread t1 = new Thread(my1); //实例化Thread类对象
Thread t2 = new Thread(my2);
t1.start(); //启动线程
t2.start();
}
}
//打印结果
作者: 柯玲 时间: 2012-7-18 11:10
陈少文 发表于 2012-7-18 09:09
一般情况下,用Runnable接口
一是看起来好看,二,java是不能
多继承的。用Runnable接口后,还可以继承其它 ...
咋一看,我以为是看错了:实现Runnable接口怎么可能会出现会出两个线程拥有独立的资源?
建议LS以后不要再举这种例子了,以免本来对这个知识点模糊的人更模糊了
既然实现Runnable,肯定是考虑到需要资源共享,即实现多线程。而怎样实现多线程呢?肯定是只需要一个资源的对象。
你这里创建了共享资源的两个对象,又分别调用单独的线程跑,这样就显得实现Runnable和继承Thread类没有多大的区别。
这个例子继承Thread还可以让别人理解继承Thread类的弊端。 这种调用Runnable子类的方式就是把Runnable的优点覆盖掉了。
如果我也不懂,看了你的这段程序以后,就觉得继承Thread和实现Runnable根本没什么区别嘛! 所以要强调下实现Runnable是因为Runnable可以利用Thread(Runnable r)这个构造函数,只创建一个资源对象,实现多个线程资源共享,也就是上面我写的例子。至于java支持单继承只是其中很小的一个原因
作者: 王宝康 时间: 2012-7-18 12:06
本帖最后由 王宝康 于 2012-7-18 12:07 编辑
其实这个问题可以从继承和实现的角度去看,
如果类 Zi 具有类 Fu 的全部属性和方法,而且又具有自己特有的某些属性和方法,则把类 Fu 称作一般类,把类 Zi 称作特殊类。
特殊类的对象拥有其一般类的全部或部分属性与方法,称作特殊类对一般类的继承,特殊类可以复写一般类的中的方法,
通过继承Thread类来创建线程其实就是运用了,子类复写父类的run()方法这个特性。
java中不允许多继承,也就是说类C同时具有类A和类B的全部属性和方法,类C只能继承其中之一,一个类只能有一个直接父类,但是可以实现多个接口,这时候就可以通过实现接口的方式来实现,你可以把你的类要提供的所有服务定义在接口中,而不提供实现,这样类C就可以通过实现接口来扩展自身的功能。
通过实现接口来创建线程呢,你就可以再去继承有针对性的其他类了,而只是通过实现Runnable接口来实现线程的运行。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |