1.死锁 JAVA中文站社区门户|$Ny8ja"{.P$Y
多线程编程在实际的网络程序开发中,在客户端程序实现中使用的比较简单,但是在服务器端程序实现中却不仅是大量使用,而且会出现比客户端更多的问题。
Kl2b,t?FrvA%K
TX0/X @ Z 另外一个容易在服务器端出现的多线程问题是——死锁。死锁指两个或两个以上的线程为了使用某个临界资源而无限制的等待下去。还是以前面卫生间的例子来说明死锁,例如两个人都同时到达卫生间,而且两个人都比较礼貌,第一个人和第二个人说:你先吧,第二个人和第一个人说:你先吧。这两个人就这样一直在互相礼让,谁也不进入,这种现象就是死锁。这里的两个人就好比是线程,而卫生间在这里就是临界资源,而由于这两个线程在一直谦让,谁也不使用临界资源。JAVA中文站社区门户)Y ^.hi1U
!n8^jV+J*v9` F 死锁不仅使程序无法达到预期实现的功能,而且浪费系统的资源,所以在服务器端程序中危害比较大,在实际的服务器端程序开发中,需要注意避免死锁。
9rd7k2~mEn*@
@+B7r-Iq:Y 而死锁的检测比较麻烦,而且不一定每次都出现,这就需要在测试服务器端程序时,有足够的耐心,仔细观察程序执行时的性能检测,如果发现执行的性能显著降低,则很可能是发生了死锁,然后再具体的查找死锁出现的原因,并解决死锁的问题。
@ ]d"S6NA JAVA中文站社区门户9A"uo&p*C%N
死锁出现的最本质原因还是逻辑处理不够严谨,在考虑时不是很周全,所以一般需要修改程序逻辑才能够很好的解决死锁。
-F!_Yq7S&o:uT~ JAVA中文站社区门户,Z5X;z,W l%/
2. 线程优先级JAVA中文站社区门户.M;G#Z}+D;]Y
"zs|| apU/5h 在日常生活中,例如火车售票窗口等经常可以看到“XXX优先”,那么多线程编程中每个线程是否也可以设置优先级呢?
S:L!w e"^
S s`ctS.G F'^ 在多线程编程中,支持为每个线程设置优先级。优先级高的线程在排队执行时会获得更多的CPU执行时间,得到更快的响应。在实际程序中,可以根据逻辑的需要,将需要得到及时处理的线程设置成较高的优先级,而把对时间要求不高的线程设置成比较低的优先级。
1t-` U.Z2bbx3vF
~+K^.wl+f*G-o^5@ 在Thread类中,总计规定了三个优先级,分别为:
*Y9tPY _QX JAVA中文站社区门户$/1fx$ZK
l MAX_PRIORITY——最高优先级JAVA中文站社区门户&d Q4r]]
JAVA中文站社区门户E:pn S+WA/KXn d
l NORM_PRIORITY——普通优先级,也是默认优先级JAVA中文站社区门户:Pv0uc)^9Xu"H
'Npr T k6A2cy G l MIN_PRIORITY——最低优先级JAVA中文站社区门户(AIl;nz ^
*p!P ZC#x ^Ds 在前面创建的线程对象中,由于没有设置线程的优先级,则线程默认的优先级是NORM_PRIORITY,在实际使用时,也可以根据需要使用Thread类中的setPriority方法设置线程的优先级,该方法的声明为:JAVA中文站社区门户#f;FqazVo
!OvM-V1{[/? public final void setPriority(int newPriority)
+fUYf-H6I'W#uuT JAVA中文站社区门户G4tpms8~%L3m(T
假设t是一个初始化过的线程对象,需要设置t的优先级为最高,则实现的代码为:
7K$W)My3qjD JAVA中文站社区门户T}1x_ I?7^H
t. setPriority(Thread. MAX_PRIORITY);JAVA中文站社区门户/R%C1B.Zp$i6hl:iKv
qwMli&k 这样,在该线程执行时将获得更多的执行机会,也就是优先执行。如果由于安全等原因,不允许设置线程的优先级,则会抛出SecurityException异常。JAVA中文站社区门户fA)de&Q,q N
JAVA中文站社区门户 s [3s {y
下面使用一个简单的输出数字的线程演示线程优先级的使用,实现的示例代码如下:JAVA中文站社区门户-m| h/s5B
4x6a}"I)DP8K/I+Z,P
9X4~ z;_B T3{8f package priority; JAVA中文站社区门户~3~"k5PAhk"h /** JAVA中文站社区门户'D0L(D fU%Q aI/U * 测试线程优先级 JAVA中文站社区门户{8J;_A/XN * author by http://www.bt285.cn http://www.5a520.cn JAVA中文站社区门户7dFgnxjD,} */ 9D#/$N#u&MH.a:[x P public class TestPriority { Vsv,TNdC public static void main(String[] args) { JAVA中文站社区门户p:T5Xqc ?? PrintNumberThread p1 = new PrintNumberThread("高优先级"); JAVA中文站社区门户{(ke,B"/,^3I PrintNumberThread p2 = new PrintNumberThread("普通优先级"); JAVA中文站社区门户~*[+H{1D {Pa9@ PrintNumberThread p3 = new PrintNumberThread("低优先级"); 7eaz^4CKp,M6]w p1.setPriority(Thread.MAX_PRIORITY); JAVA中文站社区门户!k1G g9C%R)E@&n p2.setPriority(Thread.NORM_PRIORITY); JAVA中文站社区门户-D$P(E,Vq,s p3.setPriority(Thread.MIN_PRIORITY); p#N Y+v-r G / p1.start(); 1L7@EQ%Scst/P p2.start(); JAVA中文站社区门户 ]6B2]-d SOW p3.start(); /w0~JeLk7T } a;gG2w"g ? H2uj } v| eBY.W:rc package priority; o;Yv{h6[R /** bC@9O a0N?!cL * 输出数字的线程 S J}Sl */ JAVA中文站社区门户(P3Q @"l5jZJ k@:[ public class PrintNumberThread extends Thread { JAVA中文站社区门户 _|'LcH#E String name; JAVA中文站社区门户9Mk+Fr{)x B-A@$N public PrintNumberThread(String name){ JAVA中文站社区门户us%L] A `2MyT#j this.name = name; m,Q#D(J hx#]6OyJ/| } JAVA中文站社区门户Sr;]"gpz public void run(){ JAVA中文站社区门户%]!j3mDp/c try{ JAVA中文站社区门户IWi/_@+p for(int i = 0;i < 10;i++){ %/q?^B;Z:] System.out.println(name + ":" + i); JAVA中文站社区门户3P ~*m!J s'E!w } JAVA中文站社区门户o.JgR cq!/:q }catch(Exception e){} JAVA中文站社区门户{i,yXJ } JAVA中文站社区门户Sr*Ssx voN } |
8x I)sT.]
l%cmBp;@(s 程序的一种执行结果为:JAVA中文站社区门户&e'Gr4eeS
TJ0/+~*/ 高优先级:0
M|Z-Ch JAVA中文站社区门户'[#F#/ @q.m
高优先级:1
+cc!O|!y+xv!V3x
.W/E;mm/bQ4wl 高优先级:2JAVA中文站社区门户e^ oD2AB L
/n!/ j3@?t 普通优先级:0JAVA中文站社区门户S&~q#G7m;V B
JAVA中文站社区门户)[M6I.l7}{9W @
高优先级:3JAVA中文站社区门户dJ Y,? kX%@ _r
'`7UQXWb 普通优先级:1
xz Y8i$cM JAVA中文站社区门户Z"HfHBB)x
高优先级:4JAVA中文站社区门户k?!X){` ~
khE$y;MH)eS 普通优先级:2JAVA中文站社区门户d+N)c4DSO
JAVA中文站社区门户%F3[$lw|-O
高优先级:5JAVA中文站社区门户2{tA6l6L6| p
JAVA中文站社区门户,fu Ki-_ i6s3j o0Z
高优先级:6
H+| j_EI{
g)_)ZBW9G3`GUs 高优先级:7
PxM)p9a|c)I4{8X3AF JAVA中文站社区门户5K9m.fY/yl7h
高优先级:8JAVA中文站社区门户Tc LP a4r)]-Di
JAVA中文站社区门户3C4W M~$ct/n;k
高优先级:9
WYy Q YUe6f
)^ol FWg5P 普通优先级:3JAVA中文站社区门户8s#{/?9|-B#Y]
JAVA中文站社区门户(u//}8FY8SM/Jf)h8|
普通优先级:4JAVA中文站社区门户,B vhN!E4_WO
1{/Vo Yp4ub 普通优先级:5JAVA中文站社区门户${t%t_5Oj]i8Jl
nz)vH gJM.?` 普通优先级:6JAVA中文站社区门户[8?@#d.DeB
JAVA中文站社区门户!N3V6U2j0I g,p8^2m
普通优先级:7JAVA中文站社区门户N$C8Xln
_9c:v}:m(TU 普通优先级:8
1~x+x%X!lHK!er#^
Ud'?4X3x 普通优先级:9JAVA中文站社区门户*@t5AR [Gt6AU~`y/|
.V5H5D Yr$W%P+O^{ 低优先级:0JAVA中文站社区门户/XGZaK-G
"[;dw2M w8[-l 低优先级:1
3nM Z LE5x/V9j
_X(IRTw.Z9FAI 低优先级:2
x0G0U-S4Xup9n JAVA中文站社区门户@1}hFM/?gJ%G
低优先级:3JAVA中文站社区门户1R,l1bBx
`2z.qc1z V8H 低优先级:4JAVA中文站社区门户3nmA ofOa
JAVA中文站社区门户 Q^/N `-d
低优先级:5
BY])e6p'z
},pUr4T 低优先级:6
3w#N.H7jc;B%bd Tl,T JAVA中文站社区门户y#_ {*m%W6m
低优先级:7JAVA中文站社区门户&OGz(E5YX@ VZ_ s U
JAVA中文站社区门户8?/Q,{E{^QL
低优先级:8JAVA中文站社区门户,|PRW:{2SU)cu*u
JAVA中文站社区门户XTu7m;r v;F-h m
低优先级:9JAVA中文站社区门户v U6N-EH7F/i7[
5ROQ7V7?0Y1b(S 在该示例程序,PrintNumberThread线程实现的功能是输出数字,每次数字输出之间没有设置时间延迟,在测试类TestPriority中创建三个PrintNumberThread类型的线程对象,然后分别设置线程优先级是最高、普通和最低,接着启动线程执行程序。从执行结果可以看出高优先级的线程获得了更多的执行时间,首先执行完成,而低优先级的线程由于优先级较低,所以最后一个执行结束。JAVA中文站社区门户;lfKc W3ng
JAVA中文站社区门户4U3y0c,v?-| U
其实,对于线程优先级的管理主要由系统的线程调度实现,较高优先级的线程优先执行,所以可以通过设置线程的优先级影响线程的执行。JAVA中文站社区门户Se]0@ aEt9m
JAVA中文站社区门户u4gUnA-k9Eh G
3 总结
VOU.dZ5R
8ot|7P+/x 关于多线程的基础知识就介绍这么多,在本章中介绍了线程的概念、线程的实现方式以及使用多线程时会遇到的问题以及解决办法,而需要建立多线程的概念,也就是并发编程的概念还需要进行比较多的练习,理解多线程的概念并熟悉多线程的编程。
9[FofGZ5gy7h JAVA中文站社区门户v$X-F/2B,f*r.E(u
而关于多线程编程的高级知识,如线程组等则可以在熟悉了线程的基本概念以后再进行更加深入的学习。
'k|#{1Jt0C2N8|