阅读提要:在引入Java多线程技术后
![](/icons/10744dou.gif)
几乎所有应用
![](/icons/10744chengxu.gif)
![](/icons/10744de.gif)
开发在性能上都得到了很大
![](/icons/10744de.gif)
改进
![](/icons/10744dou2.gif)
本文将通过探讨超线程技术以及新出现
![](/icons/10744de.gif)
多核心Intel处理器技术来分析这些线程技术是怎样成为Java编程
![](/icons/10744de.gif)
![](/icons/10744yi.gif)
个标准部分
![](/icons/10744de.gif)
![](/icons/10744yi.gif)
、Java环境下
![](/icons/10744de.gif)
多线程技术
构建线程化
![](/icons/10744de.gif)
应用
![](/icons/10744chengxu.gif)
往往会对
![](/icons/10744chengxu.gif)
带来重要
![](/icons/10744de.gif)
性能影响
![](/icons/10744dou2.gif)
例如
![](/icons/10744dou.gif)
请考虑这样
![](/icons/10744yi.gif)
个
![](/icons/10744chengxu.gif)
![](/icons/10744dou.gif)
它从磁盘读取大量数据并且在把它们写到屏幕的前处理这些数据(例如
![](/icons/10744yi.gif)
个DVD播放器)
![](/icons/10744dou2.gif)
在
![](/icons/10744yi.gif)
个传统
![](/icons/10744de.gif)
单线程
![](/icons/10744chengxu.gif)
(今天所使用
![](/icons/10744de.gif)
大多数客户端
![](/icons/10744chengxu.gif)
)上
![](/icons/10744dou.gif)
![](/icons/10744yi.gif)
次只有
![](/icons/10744yi.gif)
个任务执行
![](/icons/10744dou.gif)
每
![](/icons/10744yi.gif)
个这些活动分别作为
![](/icons/10744yi.gif)
个序列
![](/icons/10744de.gif)
区别阶段发生
![](/icons/10744dou2.gif)
只有在
![](/icons/10744yi.gif)
块已定义大小
![](/icons/10744de.gif)
数据读取完成时才能进行数据处理
![](/icons/10744dou2.gif)
因此
![](/icons/10744dou.gif)
能处理数据
![](/icons/10744de.gif)
![](/icons/10744chengxu.gif)
逻辑直到磁盘读操作完成后才得到执行
![](/icons/10744dou2.gif)
这将导致非常差
![](/icons/10744de.gif)
性能问题
![](/icons/10744dou2.gif)
在
![](/icons/10744yi.gif)
个多线程
![](/icons/10744chengxu.gif)
中
![](/icons/10744dou.gif)
可以分配
![](/icons/10744yi.gif)
个线程来读取数据
![](/icons/10744dou.gif)
让另
![](/icons/10744yi.gif)
个线程来处理数据
![](/icons/10744dou.gif)
而让第 3个线程把数据输送到图形卡上去
![](/icons/10744dou2.gif)
这 3个线程可以并行运行;这样以来
![](/icons/10744dou.gif)
在磁盘读取数据
![](/icons/10744de.gif)
同时仍然可以处理数据
![](/icons/10744dou.gif)
从而提高了整体
![](/icons/10744chengxu.gif)
![](/icons/10744de.gif)
性能
![](/icons/10744dou2.gif)
许多大量
![](/icons/10744de.gif)
举例
![](/icons/10744chengxu.gif)
都可以被设计来同时做两件事情以进
![](/icons/10744yi.gif)
步提高性能
![](/icons/10744dou2.gif)
Java虚拟机(JVM)本身就是基于此原因广泛使用了多线程技术
![](/icons/10744dou2.gif)
本文将讨论创建多线程Java代码以及
![](/icons/10744yi.gif)
些进行并行
![](/icons/10744chengxu.gif)
设计
![](/icons/10744de.gif)
最好练习;另外还介绍了对开发者极为有用
![](/icons/10744de.gif)
![](/icons/10744yi.gif)
些工具和资源
![](/icons/10744dou2.gif)
篇幅所限
![](/icons/10744dou.gif)
不可能全面论述这些问题
![](/icons/10744dou.gif)
所以我想只是重点提
![](/icons/10744yi.gif)
下极重要
![](/icons/10744de.gif)
地方并提供给你相应
![](/icons/10744de.gif)
参考信息
![](/icons/10744dou2.gif)
2、线程化Java代码
所有
![](/icons/10744de.gif)
![](/icons/10744chengxu.gif)
都至少使用
![](/icons/10744yi.gif)
个线程
![](/icons/10744dou2.gif)
在C/C
![](/icons/10744jiajia.gif)
和Java中
![](/icons/10744dou.gif)
这是指用对
![](/icons/10744main.gif)
![](/icons/10744kh.gif)
![](/icons/10744de.gif)
![](/icons/10744diaoyong.gif)
而启动
![](/icons/10744de.gif)
那个线程
![](/icons/10744dou2.gif)
另外线程
![](/icons/10744de.gif)
创建需要若干步骤:创建
![](/icons/10744yi.gif)
个新线程
![](/icons/10744dou.gif)
然后指定给它某种工作
![](/icons/10744dou2.gif)
![](/icons/10744yi.gif)
旦工作做完
![](/icons/10744dou.gif)
该线程将自动被JVM所杀死
![](/icons/10744dou2.gif)
Java提供两个思路方法来创建线程并且指定给它们工作
![](/icons/10744dou2.gif)
第
![](/icons/10744yi.gif)
种思路方法是子类化Java
![](/icons/10744de.gif)
Thread类(在java.lang包中)
![](/icons/10744dou.gif)
然后用该线程
![](/icons/10744de.gif)
工作
![](/icons/10744hanshu.gif)
重载run
![](/icons/10744kh.gif)
思路方法
![](/icons/10744dou2.gif)
下面是这种思路方法
![](/icons/10744de.gif)
![](/icons/10744yi.gif)
个举例:
public
![](/icons/10744class.gif)
SimpleThread extends Thread {
public SimpleThread(String str) {
super(str);
}
public void run
![](/icons/10744kh.gif)
{
for (
![](/icons/10744int.gif)
i = 0; i < 10; i
![](/icons/10744jiajia.gif)
) {
![](/icons/10744System.gif)
.out.pr
![](/icons/10744int.gif)
ln(i + " " + getName
![](/icons/10744kh.gif)
);
try {
sleep((long)(Math.random
![](/icons/10744kh.gif)
* 1000));
} catch (InterruptedException e) {}
}
![](/icons/10744System.gif)
.out.pr
![](/icons/10744int.gif)
ln("DONE! " + getName
![](/icons/10744kh.gif)
);
}
}
这个类子类化Thread并且提供它自己
![](/icons/10744de.gif)
run
![](/icons/10744kh.gif)
思路方法
![](/icons/10744dou2.gif)
上面代码中
![](/icons/10744de.gif)
![](/icons/10744hanshu.gif)
运行
![](/icons/10744yi.gif)
个循环来打印传送过来
![](/icons/10744de.gif)
![](/icons/10744zifu.gif)
串到屏幕上
![](/icons/10744dou.gif)
然后等待
![](/icons/10744yi.gif)
个随机
![](/icons/10744de.gif)
时间数目
![](/icons/10744dou2.gif)
在循环十次后
![](/icons/10744dou.gif)
该
![](/icons/10744hanshu.gif)
打印"DONE!"
![](/icons/10744dou.gif)
然后退出-并由它杀死这个线程
![](/icons/10744dou2.gif)
下面是创建线程
![](/icons/10744de.gif)
主
![](/icons/10744hanshu.gif)
:
public
![](/icons/10744class.gif)
TwoThreadsDemo {
public
![](/icons/10744static.gif)
void
![](/icons/10744main.gif)
(String
![](/icons/10744zhk2.gif)
args) {
![](/icons/10744new.gif)
SimpleThread("Do it!").start
![](/icons/10744kh.gif)
;
![](/icons/10744new.gif)
SimpleThread("Definitely not!").start
![](/icons/10744kh.gif)
;
}
}
注意该代码极为简单:
![](/icons/10744hanshu.gif)
开始
![](/icons/10744dou.gif)
给定
![](/icons/10744yi.gif)
个名字(它是该线程将要打印输出
![](/icons/10744de.gif)
![](/icons/10744zifu.gif)
串)并且
![](/icons/10744diaoyong.gif)
start
![](/icons/10744kh.gif)
![](/icons/10744dou2.gif)
然后
![](/icons/10744dou.gif)
start
![](/icons/10744kh.gif)
将
![](/icons/10744diaoyong.gif)
run
![](/icons/10744kh.gif)
思路方法
![](/icons/10744dou2.gif)
![](/icons/10744chengxu.gif)
![](/icons/10744de.gif)
结果如下所示:
0 Do it!
0 Definitely not!
1 Definitely not!
2 Definitely not!
1 Do it!
2 Do it!
3 Do it!
3 Definitely not!
4 Do it!
4 Definitely not!
5 Do it!
5 Definitely not!
6 Do it!
7 Do it!
6 Definitely not!
8 Do it!
7 Definitely not!
8 Definitely not!
9 Do it!
DONE! Do it!
9 Definitely not!
DONE! Definitely not!
正如你所看到
![](/icons/10744de.gif)
![](/icons/10744dou.gif)
这两个线程
![](/icons/10744de.gif)
输出结果纠合到
![](/icons/10744yi.gif)
起
![](/icons/10744dou2.gif)
在
![](/icons/10744yi.gif)
个单线程
![](/icons/10744chengxu.gif)
中
![](/icons/10744dou.gif)
所有
![](/icons/10744de.gif)
"Do it!"命令将
![](/icons/10744yi.gif)
起打印
![](/icons/10744dou.gif)
后面跟着输出"Definitely not!"
![](/icons/10744dou2.gif)
这个
![](/icons/10744chengxu.gif)
![](/icons/10744de.gif)
区别运行将产生区别
![](/icons/10744de.gif)
结果
![](/icons/10744dou2.gif)
这种不确定性来源于两个方面:在循环中有
![](/icons/10744yi.gif)
个随机
![](/icons/10744de.gif)
暂停;更为重要
![](/icons/10744de.gif)
是
![](/icons/10744dou.gif)
![](/icons/10744yinwei.gif)
线程执行时间没法保证
![](/icons/10744dou2.gif)
这是
![](/icons/10744yi.gif)
个关键
![](/icons/10744de.gif)
原则
![](/icons/10744dou2.gif)
JVM将根据它自己
![](/icons/10744de.gif)
时间表运行这些进程(虚拟机
![](/icons/10744yi.gif)
般支持尽可能快地运行这些线程
![](/icons/10744dou.gif)
但是没法保证何时运行
![](/icons/10744yi.gif)
个给定线程)
![](/icons/10744dou2.gif)
对于每个线程可以使
![](/icons/10744yi.gif)
个优先级和的相关联以确保关键线程被JVM处理在次要
![](/icons/10744de.gif)
线程的前
![](/icons/10744dou2.gif)
启动
![](/icons/10744yi.gif)
个线程
![](/icons/10744de.gif)
第 2种思路方法是使用
![](/icons/10744yi.gif)
个实现Runnable接口
![](/icons/10744de.gif)
类-这个接口也定义在java.lang中
![](/icons/10744dou2.gif)
这个Runnable接口指定
![](/icons/10744yi.gif)
个run
![](/icons/10744kh.gif)
思路方法-然后该思路方法成为线程
![](/icons/10744de.gif)
主
![](/icons/10744hanshu.gif)
![](/icons/10744dou.gif)
类似于前面
![](/icons/10744de.gif)
代码
![](/icons/10744dou2.gif)
现在
![](/icons/10744dou.gif)
Java
![](/icons/10744chengxu.gif)
![](/icons/10744de.gif)
![](/icons/10744yi.gif)
般风格是支持继承
![](/icons/10744de.gif)
接口
![](/icons/10744dou2.gif)
通过使用接口
![](/icons/10744dou.gif)
![](/icons/10744yi.gif)
个类在后面仍然能够继承(子类化)-如果必要
![](/icons/10744de.gif)
话(例如
![](/icons/10744dou.gif)
如果该类要在后面作为
![](/icons/10744yi.gif)
个applet使用
![](/icons/10744de.gif)
话
![](/icons/10744dou.gif)
就会发生这种情况)
![](/icons/10744dou2.gif)
3、线程
![](/icons/10744de.gif)
含义
在采用多线程技术增强性能
![](/icons/10744de.gif)
同时
![](/icons/10744dou.gif)
它也增加了
![](/icons/10744chengxu.gif)
内部运行
![](/icons/10744de.gif)
复杂性
![](/icons/10744dou2.gif)
这种复杂性主要是由线程的间
![](/icons/10744de.gif)
交互引起
![](/icons/10744de.gif)
![](/icons/10744dou2.gif)
熟悉这些问题是很重要
![](/icons/10744de.gif)
![](/icons/10744dou.gif)
![](/icons/10744yinwei.gif)
随着越来越多
![](/icons/10744de.gif)
核心芯片加入到Intel处理器中
![](/icons/10744dou.gif)
要使用
![](/icons/10744de.gif)
线程数目也将相应地增长
![](/icons/10744dou2.gif)
如果在创建多线程
![](/icons/10744chengxu.gif)
时不能很好地理解这些问题
![](/icons/10744dou.gif)
那么是调试时将很难发现
![](/icons/10744cuowu.gif)
![](/icons/10744dou2.gif)
因此
![](/icons/10744dou.gif)
让我们先看
![](/icons/10744yi.gif)
下这些问题及其解决办法
![](/icons/10744dou2.gif)
等待另
![](/icons/10744yi.gif)
个线程完成:假定我们有
![](/icons/10744yi.gif)
个整型
![](/icons/10744shuzu.gif)
要进行处理
![](/icons/10744dou2.gif)
我们可以遍历这个
![](/icons/10744shuzu.gif)
![](/icons/10744dou.gif)
每次
![](/icons/10744yi.gif)
个整数并执行相应
![](/icons/10744de.gif)
操作
![](/icons/10744dou2.gif)
或
![](/icons/10744dou.gif)
更高效地
![](/icons/10744dou.gif)
我们可以建立多个线程
![](/icons/10744dou.gif)
这样以来让每个线程处理
![](/icons/10744shuzu.gif)
![](/icons/10744de.gif)
![](/icons/10744yi.gif)
部分
![](/icons/10744dou2.gif)
假定我们在开始下
![](/icons/10744yi.gif)
步的前必须等待所有
![](/icons/10744de.gif)
线程结束
![](/icons/10744dou2.gif)
为了暂时同步线程的间
![](/icons/10744de.gif)
活动
![](/icons/10744dou.gif)
这些线程使用了join
![](/icons/10744kh.gif)
思路方法-它使得
![](/icons/10744yi.gif)
个线程等待另
![](/icons/10744yi.gif)
个线程
![](/icons/10744de.gif)
完成
![](/icons/10744dou2.gif)
加入
![](/icons/10744de.gif)
线程(线程B)等待被加入
![](/icons/10744de.gif)
线程(线程A)
![](/icons/10744de.gif)
完成
![](/icons/10744dou2.gif)
在join
![](/icons/10744kh.gif)
中
![](/icons/10744de.gif)
![](/icons/10744yi.gif)
个可选
![](/icons/10744de.gif)
超时值使得线程B可以继续处理其它工作-如果线程A在给定
![](/icons/10744de.gif)
时间帧内还没有终止
![](/icons/10744de.gif)
话
![](/icons/10744dou2.gif)
这个问题将触及到线程
![](/icons/10744de.gif)
核心复杂性-等待线程
![](/icons/10744de.gif)
问题
![](/icons/10744dou2.gif)
下面我们将讨论这个问题
![](/icons/10744dou2.gif)
在锁定对象上等待:假定我们编写
![](/icons/10744yi.gif)
个航空公司座位分配系统
![](/icons/10744dou2.gif)
在开发这种大型
![](/icons/10744de.gif)
![](/icons/10744chengxu.gif)
时
![](/icons/10744dou.gif)
为每个连接到该软件Software
![](/icons/10744de.gif)
用户分配
![](/icons/10744yi.gif)
个线程是很经常
![](/icons/10744de.gif)
![](/icons/10744dou.gif)
如
![](/icons/10744yi.gif)
个线程对应
![](/icons/10744yi.gif)
个机票销售员(在很大
![](/icons/10744de.gif)
系统中
![](/icons/10744dou.gif)
情况并非总是如此)
![](/icons/10744dou2.gif)
如果有两个用户同时想分配同
![](/icons/10744yi.gif)
个座位
![](/icons/10744dou.gif)
就会出现问题
![](/icons/10744dou2.gif)
除非采取特殊
![](/icons/10744de.gif)
措施
![](/icons/10744dou.gif)
否则
![](/icons/10744yi.gif)
个线程将分配该座位而另
![](/icons/10744yi.gif)
个线程将会在做相同
![](/icons/10744de.gif)
事情
![](/icons/10744dou2.gif)
两个用户都会认为他们在这趟航班上拥有
![](/icons/10744yi.gif)
个分配
![](/icons/10744de.gif)
位子
![](/icons/10744dou2.gif)
为了避免两个线程同时修改
![](/icons/10744yi.gif)
样
![](/icons/10744de.gif)
数据项
![](/icons/10744dou.gif)
我们让
![](/icons/10744yi.gif)
个线程在修改数据前锁定数据项
![](/icons/10744dou2.gif)
用这种思路方法
![](/icons/10744dou.gif)
当第 2个线程开始作修改时
![](/icons/10744dou.gif)
它将等待到第
![](/icons/10744yi.gif)
个线程释放锁为止
![](/icons/10744dou2.gif)
当这种发生时
![](/icons/10744dou.gif)
线程将会看到座位已被分配
![](/icons/10744dou.gif)
而对于座位分配
![](/icons/10744de.gif)
请求就会失败
![](/icons/10744dou2.gif)
两个线程竞争分配座位
![](/icons/10744de.gif)
问题也就是著名
![](/icons/10744de.gif)
竞争条件问题
![](/icons/10744dou.gif)
而当竞争发生时有可能导致系统
![](/icons/10744de.gif)
泄漏
![](/icons/10744dou2.gif)
为此
![](/icons/10744dou.gif)
最好
![](/icons/10744de.gif)
办法就是锁定任何代码-该代码存取
![](/icons/10744yi.gif)
个可由多个线程共同存取
![](/icons/10744de.gif)
变量
![](/icons/10744dou2.gif)
在Java中存在好几种锁选择
![](/icons/10744dou2.gif)
其中最为常用
![](/icons/10744de.gif)
是使用同步机制
![](/icons/10744dou2.gif)
当
![](/icons/10744yi.gif)
个思路方法
![](/icons/10744de.gif)
签名包含同步时
![](/icons/10744dou.gif)
在任何给定时间只有
![](/icons/10744yi.gif)
个线程能够执行这个思路方法
![](/icons/10744dou2.gif)
然后
![](/icons/10744dou.gif)
当该思路方法完成执行时
![](/icons/10744dou.gif)
对该思路方法
![](/icons/10744de.gif)
锁定即被解除
![](/icons/10744dou2.gif)
例如
![](/icons/10744dou.gif)
protected synchronized
![](/icons/10744int.gif)
reserveSeat ( Seat seat_number ){
![](/icons/10744if.gif)
( seat_number.getReserved
![](/icons/10744dd.gif)
false ){
seat_number.
![](/icons/10744set.gif)
Reserved
![](/icons/10744kh.gif)
;
![](/icons/10744return.gif)
( 0 );
}
![](/icons/10744return.gif)
( -1 );
}
就是
![](/icons/10744yi.gif)
个思路方法-在这种思路方法中每次只运行
![](/icons/10744yi.gif)
个线程
![](/icons/10744dou2.gif)
这种锁机制就打破了上面所描述
![](/icons/10744de.gif)
竞争条件
![](/icons/10744dou2.gif)
使用同步是处理线程间交互
![](/icons/10744de.gif)
几种思路方法中
![](/icons/10744de.gif)
![](/icons/10744yi.gif)
种
![](/icons/10744dou2.gif)
J2SE 5.0中添加了若干方便
![](/icons/10744de.gif)
思路方法来锁定对象
![](/icons/10744dou2.gif)
大多数这些思路方法可以在包java.util.concurrent.locks中找到-
![](/icons/10744yi.gif)
旦你熟悉了Java线程
![](/icons/10744dou.gif)
就应该对它进行详细
![](/icons/10744de.gif)
研究
![](/icons/10744dou2.gif)
在锁机制解决了竞争条件
![](/icons/10744de.gif)
同时
![](/icons/10744dou.gif)
它们也带来了新
![](/icons/10744de.gif)
复杂性
![](/icons/10744dou2.gif)
在这种情况下
![](/icons/10744dou.gif)
最困难
![](/icons/10744de.gif)
问题就是死锁
![](/icons/10744dou2.gif)
假定线程A在等待线程B
![](/icons/10744dou.gif)
并且线程B在等待线程A
![](/icons/10744dou.gif)
那么这两个线程将永远被锁定-这正是术语死锁
![](/icons/10744de.gif)
意义
![](/icons/10744dou2.gif)
死锁问题可能很难判定
![](/icons/10744dou.gif)
并且必须相当小心以确保在线程的间没有这种依赖性
![](/icons/10744dou2.gif)
4、使用线程池
如前所提及
![](/icons/10744dou.gif)
在线程完成执行时
![](/icons/10744dou.gif)
它们将被JVM杀死而分配给它们
![](/icons/10744de.gif)
内存将被垃圾回收机制所回收
![](/icons/10744dou2.gif)
不断地创建和毁灭线程所带来
![](/icons/10744de.gif)
麻烦是它浪费了时钟周期
![](/icons/10744dou.gif)
![](/icons/10744yinwei.gif)
创建线程确实耗费额外
![](/icons/10744de.gif)
时间
![](/icons/10744dou2.gif)
![](/icons/10744yi.gif)
个通用
![](/icons/10744de.gif)
且最好
![](/icons/10744de.gif)
实现是在
![](/icons/10744chengxu.gif)
运行
![](/icons/10744de.gif)
早期就分配
![](/icons/10744yi.gif)
组线程(称为
![](/icons/10744yi.gif)
个线程池)
![](/icons/10744dou.gif)
然后在这些线程可用时再使用它们
![](/icons/10744dou2.gif)
通过使用这种方案
![](/icons/10744dou.gif)
在创建时分配给
![](/icons/10744yi.gif)
个线程指定
![](/icons/10744de.gif)
功能就是呆在线程池中并且等待分配
![](/icons/10744yi.gif)
项工作
![](/icons/10744dou2.gif)
然后
![](/icons/10744dou.gif)
当分配
![](/icons/10744de.gif)
工作完成时
![](/icons/10744dou.gif)
该线程被返回到线程池
![](/icons/10744dou2.gif)
J2SE 5.0引入了java.util.concurrent包-它包括了
![](/icons/10744yi.gif)
个预先构建
![](/icons/10744de.gif)
线程池框架-这大大便利了上述思路方法
![](/icons/10744de.gif)
实现
![](/icons/10744dou2.gif)
有关Java线程池
![](/icons/10744de.gif)
更多信息及
![](/icons/10744yi.gif)
部教程
![](/icons/10744dou.gif)
请参见http://java.sun.com/developer/JDCTechTips/2004/tt1116.html#2
![](/icons/10744dou2.gif)
在设计线程
![](/icons/10744chengxu.gif)
和线程池时
![](/icons/10744dou.gif)
自然出现有关应该创建多少线程
![](/icons/10744de.gif)
问题
![](/icons/10744dou2.gif)
答案看你怎样计划使用这些线程
![](/icons/10744dou2.gif)
如果你基于分离
![](/icons/10744de.gif)
任务来用线程划分工作
![](/icons/10744dou.gif)
那么线程
![](/icons/10744de.gif)
数目等于任务
![](/icons/10744de.gif)
数目
![](/icons/10744dou2.gif)
例如
![](/icons/10744dou.gif)
![](/icons/10744yi.gif)
个字处理器可能使用
![](/icons/10744yi.gif)
个线程用于显示(在几乎所有系统中
![](/icons/10744de.gif)
主
![](/icons/10744chengxu.gif)
线程负责更新用户接口)
![](/icons/10744dou.gif)
![](/icons/10744yi.gif)
个用于标记文档
![](/icons/10744dou.gif)
第 3个用于拼写检查
![](/icons/10744dou.gif)
而第 4个用于其它后台操作
![](/icons/10744dou2.gif)
在这种情况中
![](/icons/10744dou.gif)
创建 4个线程是理想
![](/icons/10744de.gif)
并且它们提供了编写该类软件Software
![](/icons/10744de.gif)
![](/icons/10744yi.gif)
个很自然
![](/icons/10744de.gif)
思路方法
![](/icons/10744dou2.gif)
然而
![](/icons/10744dou.gif)
如果
![](/icons/10744chengxu.gif)
-象早些时候所讨论
![](/icons/10744de.gif)
那个
![](/icons/10744yi.gif)
样-使用多个线程来做类似
![](/icons/10744de.gif)
工作
![](/icons/10744dou.gif)
那么线程
![](/icons/10744de.gif)
最佳数目将是系统资源
![](/icons/10744de.gif)
反映
![](/icons/10744dou.gif)
特别是处理器上可执行管道
![](/icons/10744de.gif)
数目和处理器
![](/icons/10744de.gif)
数目
![](/icons/10744de.gif)
反映
![](/icons/10744dou2.gif)
在采用英特尔处理器超线程技术(HT技术)
![](/icons/10744de.gif)
系统上
![](/icons/10744dou.gif)
当前在每个处理器核心上有两个执行管道
![](/icons/10744dou2.gif)
最新
![](/icons/10744de.gif)
多核心处理器在每个芯片上有两个处理器核心
![](/icons/10744dou2.gif)
英特尔指出将来
![](/icons/10744de.gif)
芯片有可能具有多个核心
![](/icons/10744dou.gif)
大部分是
![](/icons/10744yinwei.gif)
额外
![](/icons/10744de.gif)
核心会带来更高
![](/icons/10744de.gif)
性能而不会从根本上增加热量或电量
![](/icons/10744de.gif)
消耗
![](/icons/10744dou2.gif)
因此
![](/icons/10744dou.gif)
管道数将会越来越多
![](/icons/10744dou2.gif)
照上面这些体系结构所作
![](/icons/10744de.gif)
算术建议
![](/icons/10744dou.gif)
在
![](/icons/10744yi.gif)
个双核心Pentium 4处理器系统上
![](/icons/10744dou.gif)
可以使用 4条执行管道并因此可以使用 4个线程将会提供理想
![](/icons/10744de.gif)
性能
![](/icons/10744dou2.gif)
在
![](/icons/10744yi.gif)
个双处理器英特尔Xeon?处理器
![](/icons/10744de.gif)
工作站上
![](/icons/10744dou.gif)
理想
![](/icons/10744de.gif)
线程数目是4
![](/icons/10744dou.gif)
![](/icons/10744yinwei.gif)
目前Xeon芯片提供HT技术但是没提供多核心模型
![](/icons/10744dou2.gif)
你可以参考下面文档来了解这些新型处理器上
![](/icons/10744de.gif)
执行管道
![](/icons/10744de.gif)
数目(http://www.
![](/icons/10744int.gif)
el.com/cd/ids/developer/asmo-na/eng/196716.htm)
![](/icons/10744dou2.gif)
5、小结
你当在平台上运行线程化
![](/icons/10744de.gif)
Java
![](/icons/10744chengxu.gif)
时
![](/icons/10744dou.gif)
你将可能想要监控在处理器上
![](/icons/10744de.gif)
加载过程和线程
![](/icons/10744de.gif)
执行
![](/icons/10744dou2.gif)
最好
![](/icons/10744de.gif)
获得这些数据和管理JVM怎样处理并行处理
![](/icons/10744de.gif)
JVM的
![](/icons/10744yi.gif)
是BEA
![](/icons/10744de.gif)
WebLogic JRockit
![](/icons/10744dou2.gif)
JRockit还有其它
![](/icons/10744yi.gif)
些由来自于BEA和Intel公司
![](/icons/10744de.gif)
工程师专门为Intel平台设计和优化
![](/icons/10744de.gif)
优点
![](/icons/10744dou2.gif)
不考虑你使用哪
![](/icons/10744yi.gif)
种JVM
![](/icons/10744dou.gif)
Intel
![](/icons/10744de.gif)
VTune Performance Analyzer将会给你
![](/icons/10744yi.gif)
个有关JVM怎样执行你
![](/icons/10744de.gif)
代码
![](/icons/10744de.gif)
很深入
![](/icons/10744de.gif)
视图-这包括每个线程
![](/icons/10744de.gif)
性能瓶颈等
![](/icons/10744dou2.gif)
另外
![](/icons/10744dou.gif)
Intel还提供了有关如何在Java环境下使用VTune Performance Analyzer
![](/icons/10744de.gif)
白皮书[PDF 2MB]
![](/icons/10744dou2.gif)
总的
![](/icons/10744dou.gif)
本文提供了线程在Java平台工作机理
![](/icons/10744de.gif)
分析
![](/icons/10744dou2.gif)
由于Intel还将继续生产HT技术
![](/icons/10744de.gif)
处理器并且发行更多
![](/icons/10744de.gif)
多核心芯片
![](/icons/10744dou.gif)
所以想从这些多管道中得到性能效益
![](/icons/10744de.gif)
压力也会增加
![](/icons/10744dou2.gif)
并且
![](/icons/10744dou.gif)
由于核心芯片数目
![](/icons/10744de.gif)
增加
![](/icons/10744dou.gif)
管道
![](/icons/10744de.gif)
数目也将相应地增加
![](/icons/10744dou2.gif)
唯
![](/icons/10744yi.gif)
![](/icons/10744de.gif)
利用它们
![](/icons/10744de.gif)
优点
![](/icons/10744de.gif)
办法就是使用多线程技术
![](/icons/10744dou.gif)
如在本文中所讨论
![](/icons/10744de.gif)
![](/icons/10744dou2.gif)
并且Java多线程
![](/icons/10744chengxu.gif)
![](/icons/10744de.gif)
优势也越来越明显