Mison(迈胜)
BlogJava
::
首页
::
新随笔
::
联系
::
聚合
::
管理
posts - 7, comments - 0, trackbacks - 0
<
2010年2月
>
日
一
二
三
四
五
六
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
常用链接
我的随笔
我的评论
我的参与
留言簿
给我留言
查看公开留言
查看私人留言
随笔档案
2010年3月 (2)
2010年2月 (5)
文章档案
2010年2月 (2)
搜索
最新评论
阅读排行榜
1. Maven2.2.1下载(233)
2. SCWCD认证之路(214)
3. 创建线程两种方式的比较(181)
4. MyEclipse卡机问题的解决(125)
5. 新鲜出炉的10年福富笔试(120)
评论排行榜
1. 2010年的技术架构建议(0)
2. 【Black设计模式】观察者模式代码解析(0)
3. Maven2.2.1下载(0)
4. 新鲜出炉的10年福富笔试(0)
5. 创建线程两种方式的比较(0)
创建线程两种方式的比较
装载:Mison(迈胜)
http://bbs.misonsoft.com/thread-1225-1-2.html
通过铁路售票程序来理解实现多线程的两种方法:通过java.lang.Thread类和通过Runnable接口
java中有两种实现多线程的方式。一是直接继承Thread类,二是实现Runnable接口。那么这两种实现多线程的方式在应用上有什么区别呢?
为了回答这个问题,我们可以通过编写一段代码来进行分析。我们用代码来模拟铁路售票系统,实现通过四个售票点发售某日某次列车的100张车票,一个售票点用一个线程表示。
我们首先这样编写这个程序:
public
class
ThreadDome1
{
public
static
void
main(String[] args)
{
ThreadTest t
=
new
ThreadTest();
t.start();
t.start();
t.start();
t.start();
}
}
class
ThreadTest
extends
Thread
{
private
int
ticket
=
100
;
public
void
run()
{
while
(
true
)
{
if
(ticket
>
0
)
{
System.out.println(Thread.currentThread().getName()
+
"
is saling ticket
"
+
ticket
--
);
}
else
{
break
;
}
}
}
}
上面的代码中,我们用ThreadTest类模拟售票处的售票过程,run方法中的每一次循环都将总票数减1,模拟卖出一张车票,同时该车票号打印出来,直接剩余的票数到零为止。在ThreadDemo1类的main方法中,我们创建了一个线程对象,并重复启动四次,希望通过这种方式产生四个线程。从运行的结果来看我们发现其实只有一个线程在运行,这个结果告诉我们:一个线程对象只能启动一个线程,无论你调用多少遍start()方法,结果只有一个线程。
我们接着修改ThreadDemo1,在main方法中创建四个Thread对象:
public
class
ThreadDemo1
{
public
static
void
main(String[] args)
{
new
ThreadTest().start();
new
ThreadTest().start();
new
ThreadTest().start();
new
ThreadTest().start();
}
}
class
ThreadTest
extends
Thread
{
private
int
ticket
=
100
;
public
void
run()
{
while
(
true
)
{
if
(ticket
>
0
)
{
System.out.println(Thread.currentThread().getName()
+
"
is saling ticket
"
+
ticket
--
);
}
else
{
break
;
}
}
}
}
这下达到目的了吗?
从结果上看每个票号都被打印了四次,即四个线程各自卖各自的100张票,而不去卖共同的100张票。这种情况是怎么造成的呢?我们需要的是,多个线程去处理同一个资源,一个资源只能对应一个对象,在上面的程序中,我们创建了四个ThreadTest对象,就等于创建了四个资源,每个资源都有100张票,每个线程都在独自处理各自的资源。
经过这些实验和分析,可以总结出,要实现这个铁路售票程序,我们只能创建一个资源对象,但要创建多个线程去处理同一个资源对象,并且每个线程上所运行的是相同的程序代码。在回顾一下使用接口编写多线程的过程。
public
class
ThreadDemo1
{
public
static
void
main(String[] args)
{
ThreadTest t
=
new
ThreadTest();
new
Thread(t).start();
new
Thread(t).start();
new
Thread(t).start();
new
Thread(t).start();
}
}
class
ThreadTest
implements
Runnable
{
private
int
tickets
=
100
;
public
void
run()
{
while
(
true
)
{
if
(tickets
>
0
)
{
System.out.println(Thread.currentThread().getName()
+
"
is saling ticket
"
+
tickets
--
);
}
}
}
}
上面的程序中,创建了四个线程,每个线程调用的是同一个ThreadTest对象中的run()方法,访问的是同一个对象中的变量(tickets)的实例,这个程序满足了我们的需求。在Windows上可以启动多个记事本程序一样,也就是多个进程使用同一个记事本程序代码。
可见,实现Runnable接口相对于继承Thread类来说,有如下显著的好处:
(1)适合多个相同程序代码的线程去处理同一资源的情况,把虚拟CPU(线程)同程序的代码,数据有效的分离,较好地体现了面向对象的设计思想。
(2)可以避免由于
Java
的单继承特性带来的局限。我们经常碰到这样一种情况,即当我们要将已经继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么,这个类就只能采用实现Runnable接口的方式了。
(3)有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程操作相同的数据,与它们的代码无关。当共享访问相同的对象时,即它们共享相同的数据。当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable接口的类的实例。
posted on 2010-02-23 09:19
Mison
阅读(181)
评论(0)
编辑
收藏
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
Chat2DB
C++博客
博问
管理