BaoYaEr
java線程學(xué)習(xí)
1. 創(chuàng)建線程
Java的線程繼承自Thread的類,處理一個名為run的方法。
class
MyThread
extends
Thread
{
private
int
i
=
0
;
public
void
run()
{
while
(
true
)
{
System.out.println(
++
i);
if
(i
>
100
)
break
;
}
}
}
public
class
program
{
public
static
void
main(String[] args)
{
new
MyThread().start();
}
}
而對于那些不能繼承 Thread 的類,可以采取實現(xiàn) Runnable 接口的方式進(jìn)行。
2. 執(zhí)行權(quán)轉(zhuǎn)交
對于暫時交出執(zhí)行權(quán),Java 提供了 Thread.yield() 方法.
class
MyThread
extends
Thread
{
public
void
run()
{
int
i
=
0
;
while
(
true
)
{
System.out.println( getName()
+
"
-----------
"
+
(
++
i));
if
(i
>
100
)
break
;
yield();
}
}
}
public
class
ThreadTest
{
public
static
void
main(String[] args)
{
MyThread t1
=
new
MyThread();
MyThread t2
=
new
MyThread();
t1.setName(
"
t1
"
);
t2.setName(
"
t2
"
);
t1.start();
t2.start();
}
}
結(jié)果:
t1-----------1
t2-----------1
t1-----------2
t2-----------2
t1-----------3
t2-----------3
t1-----------4
t2-----------4
t1-----------5
t2-----------5
.....
Java 也提供了 Thread.sleep(); 方法,但由于 Thread.sleep 可能被 interrupt( ) 方法中斷,因此必須包含在 try{} 代碼塊中。
class
MyThread
extends
Thread
{
public
void
run()
{
int
i
=
0
;
while
(
true
)
{
System.out.printf(
"
%s=%d\n
"
, getName(),
++
i);
if
(i
>
100
)
break
;
try
{
sleep(
0
);
}
catch
(InterruptedException e)
{
}
}
}
}
public
class
program
{
public
static
void
main(String[] args)
{
MyThread t1
=
new
MyThread();
MyThread t2
=
new
MyThread();
t1.setName(
"
t1
"
);
t2.setName(
"
t2
"
);
t1.start();
t2.start();
}
}
3. 優(yōu)先級
Java 使用 setPriority( ) 方法調(diào)整優(yōu)先級。
4. 背景線程
Java 使用 setDaemon() 方法。在 Java 中一般將背景線程稱之為"守護(hù)線程(daemon thread)"。需要注意的是即便背景線程未結(jié)束,進(jìn)程依然會終止。必須在線程啟動前設(shè)置。
5. 線程等待
Java 中都使用 join/Join() 方法阻止調(diào)用線程,直到某個線程結(jié)束。不過 Java 里面情況還是要復(fù)雜一些。當(dāng)某個線程處于 join 等待時,它可能會被 interrupt( ) 方法中斷,因此也得放在 try{} 代碼塊中。
package
tread;
class
ThreadT
extends
Thread
{
public
boolean
stopFlag
=
false
;
public
void
run()
{
int
i
=
0
;
while
(
!
stopFlag)
{
System.out.println(
++
i);
yield();
}
System.out.println(
"
MyThread over
"
);
}
}
class
JoinThread
extends
Thread
{
public
void
run()
{
ThreadT my
=
new
ThreadT();
my.start();
try
{
my.join();
}
catch
(InterruptedException e)
{
my.stopFlag
=
true
;
System.out.println(
"
JoinThread InterruptedException
"
);
}
}
}
public
class
JoinTest
{
public
static
void
main(String[] args)
{
JoinThread join
=
new
JoinThread();
join.start();
try
{
join.sleep(
100
*
5
);
join.interrupt();
}
catch
(InterruptedException e)
{
//
TODO Auto-generated catch block
e.printStackTrace();
}
}
}
結(jié)果:
。。。。。。
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
JoinThread InterruptedException
MyThread over
6. 資源鎖定
Java 提供了 synchronized 關(guān)鍵字用來解決多線程資源共享鎖定的問題,synchronized 可用于方法或者某個代碼段。
package
tread;
class
Res
{
String lock
=
""
;
synchronized
static
void
test()
{
for
(
int
i
=
0
; i
<
10
; i
++
)
{
System.out.println( Thread.currentThread().getName()
+
"
=========
"
+
i);
Thread.yield();
}
}
void
test2()
{
synchronized
(lock)
{
for
(
int
i
=
0
; i
<
10
; i
++
)
{
System.out.println( Thread.currentThread().getName()
+
"
========
"
+
i);
Thread.yield();
//
沒有放棄鎖
}
}
}
}
class
MyThreadA
extends
Thread
{
public
void
run()
{
new
Res().test2();
}
}
public
class
SynTest
{
public
static
void
main(String[] args)
{
MyThreadA t1
=
new
MyThreadA();
MyThreadA t2
=
new
MyThreadA();
t1.setName(
"
t1
"
);
t2.setName(
"
t2
"
);
t1.start();
t2.start();
}
}
當(dāng)我們?nèi)∠?synchronized 關(guān)鍵字時,我們會發(fā)現(xiàn) t1 和 t2 交替執(zhí)行。添加 synchronized 關(guān)鍵字以后,t2 會在 t1 執(zhí)行完成后執(zhí)行,因此對于方法的鎖定是成功的。
結(jié)果:
t1
========
0
。。。。
t1
========
7
t1
========
8
t1
========
9
t2
========
0
。。。
t2
========
8
t2
========
9
另外,需要注意的是 synchronized 是全局鎖定,也就是說對于靜態(tài)方法而言,它們會鎖定全部有此標(biāo)記的方法(盡管它們不是同一個方法);而對于對象實例,它們會鎖定同一對象全部有此標(biāo)記的方法(盡管它們不是同一個方法)。
7. 原子操作
所謂原子操作是指不會被線程調(diào)度機(jī)制打斷的操作;這種操作一旦開始,就一直運行倒結(jié)束,中間不會有任何線程切換操作。
通常所說的Java原子操作包括對非long和double型的primitive進(jìn)行賦值,以及返回這兩者之外的primitive。之所以要把它們排除在外是因為它們都比較大,而JVM的設(shè)計規(guī)范又沒有要求讀操作和賦值操作必須是原子操作(JVM可以試著去這么作,但并不保證)。不過如果你在long或double前面加了volatile,那么它就肯定是原子操作了。
看下面的例子,雖然 return i是一個原子操作,但是從獲得i的值到方法返回之間有可能被其他線程修改,因此不要主觀的認(rèn)為下面的操作是原子操作。我們還是有必要為其添加同步關(guān)鍵字synchronized。另外 ++i 和 --i 都不是原子操作,它們都涉及讀和寫兩個步驟。
public int getValue() { return i; }
《Thinking in Java》中關(guān)于最安全的做法提出了如下的方針,不過我不完全贊同。
如果你要synchronize類的一個方法,索性把所有的方法全都synchronize了。要判斷,哪個方法該synchronize,哪個方法可以不synchronize,通常是很難的,而且也沒什么把握。
刪除synchronized的時候要絕對小心。通常這么做是為了性能,但是synchronized的開銷在JDK1.3和1.4里已經(jīng)大為降低了。此外,只有在用profiler分析過,確認(rèn)synchronized確實是瓶頸的前提下才能這么作。
我們順便看看 C# 里面關(guān)于原子操作的一些狀況。C# 通過 Interlocked 類來提供原子操作的支持,稱之為互鎖操作。“互鎖操作是原子的 — 即整個操作是不能由相同變量上的另一個互鎖操作所中斷的單元。這在搶先多線程操作系統(tǒng)中是很重要的,在這樣的操作系統(tǒng)中,線程可以在從某個內(nèi)存地址加載值之后但是在有機(jī)會更改和存儲該值之前被掛起。 ”
8. 線程協(xié)同
Java用對象鎖來控制多線程安全,而所謂多線程協(xié)同無非是利用某種鎖機(jī)制讓線程暫時停頓下來,直到某個“信號”發(fā)生。為此,Java 將用來進(jìn)行多線程協(xié)同的方法放在了根 Object 上,包括 wait(); notify(); notifyAll(); 。
調(diào)用 wait() / notify() / notifyAll() 之前必須先獲取其對象鎖,否則會拋出"IllegalMonitorStateException - current thread not owner" 異常。
package
tread;
class
MyThread
extends
Thread
{
static
Object o
=
new
Object();
public
void
run()
{
synchronized
(o)
{
int
i
=
0
;
while
(
++
i
<
10
)
{
System.out.println(i);
try
{
if
(i
==
5
) o.wait();
}
catch
(InterruptedException e)
{
}
}
}
}
}
public
class
SynTest2
{
public
static
void
main(String[] args)
{
MyThread t1
=
new
MyThread();
t1.start();
while
(t1.getState()
!=
Thread.State.WAITING)
{
try
{
Thread.sleep(
100
);
}
catch
(InterruptedException e)
{
}
}
System.out.println(
"
Notify Thread
"
);
synchronized
(MyThread.o)
{
MyThread.o.notify();
}
}
}
輸出
1
2
3
4
5
Notify Thread...
6
7
8
9
在上面這個例子中,當(dāng) i 等于 5 時,我們調(diào)用了對象鎖 o 的 wait 方法阻塞線程。在 main 方法中我們循環(huán)檢查對象狀態(tài),并適時發(fā)出信號結(jié)束等待。這個例子雖然很簡單,但是由此可以處理多個線程之間的協(xié)同關(guān)系。當(dāng)然,我們還可以給 wait 方法加一個參數(shù),讓其等待特定的時間,而不是上面例子中的無限制等待。
需要注意的是 wait() 會釋放對象鎖,sleep() 則不會。接著看下面的例子。
class MyThread extends Thread {
static Object o = new Object();
public void run() {
synchronized (o) {
int i = 0;
while (++i < 10) {
System.out.printf("%s - %d\n", Thread.currentThread().getName(), i);
try
{
if (i >= 5) o.wait();
}
catch (InterruptedException e)
{
}
}
}
}
}
public class Program {
public static void main(String[] args) {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
}
}
輸出
t1 - 1
t1 - 2
t1 - 3
t1 - 4
t1 - 5
t2 - 1
t2 - 2
t2 - 3
t2 - 4
t2 - 5
9. 停止/中斷線程
線程退出最好自己實現(xiàn),在運行狀態(tài)中一直檢驗一個狀態(tài),如果這個狀態(tài)為真,就一直運行,如果外界更改了這個狀態(tài)變量,那么線程就停止運行。
Java 不推薦使用 stop() / about() / suspend() / resume() 之類的方法來停止線程。原因包括:
在調(diào)用這些方法的時候,我們不能確定線程方法執(zhí)行到何處,是否完成了特定的邏輯。
這些方法會讓線程無法正確釋放對象鎖,可能造成死鎖。
推薦的方法:
使用旗標(biāo)(flag)。
調(diào)用 interrupt()。
class MyThread extends Thread {
public boolean stopFlag = false;
public void run() {
while (!stopFlag) {
try
{
System.out.println("Thread running, " + System.currentTimeMillis());
Thread.sleep(50);
}
catch (Exception e)
{
}
}
System.out.println("Thread Stop...");
}
}
public class Program {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
try
{
Thread.sleep(100);
}
catch (Exception e)
{
}
t.stopFlag = true;
}
}
當(dāng)線程因某種原因處于阻塞等待狀態(tài)時,我們就無法使用旗標(biāo)終止它,那么改用interrupt()好了。
class MyThread extends Thread {
public void run() {
try
{
while (true) {
System.out.println("Thread running, " + System.currentTimeMillis());
synchronized (this) {
wait();
}
}
}
catch (Exception e)
{
}
System.out.println("Thread Stop...");
}
}
public class Program {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
try
{
while (t.getState() != Thread.State.WAITING) {
Thread.sleep(500);
}
t.interrupt();
}
catch (Exception e)
{
}
}
}
發(fā)表于 2007-04-11 16:24
大田斗
閱讀(737)
評論(0)
編輯
收藏
所屬分類:
java
新用戶注冊
刷新評論列表
只有注冊用戶
登錄
后才能發(fā)表評論。
網(wǎng)站導(dǎo)航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
相關(guān)文章:
mule事件驅(qū)動服務(wù)
JDK1.5中的線程池(java.util.concurrent.ThreadPoolExecutor)使用簡介
在xml的汪洋中遨游之mule篇
linux下java運行腳本
深入淺出之正則表達(dá)式【zt】
JavaClassLoader與Package機(jī)制
JTA事務(wù)初級研究
Spring2.5注釋語法
java annotation
J2SE5.0中最有趣的新特性:注釋(annotation) [zt]
<
2025年5月
>
日
一
二
三
四
五
六
27
28
29
30
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
29
30
31
1
2
3
4
5
6
7
導(dǎo)航
BlogJava
首頁
發(fā)新隨筆
發(fā)新文章
聯(lián)系
聚合
管理
統(tǒng)計
隨筆: 32
文章: 427
評論: 144
引用: 0
常用鏈接
我的隨筆
我的評論
我的參與
最新評論
留言簿
(5)
給我留言
查看公開留言
查看私人留言
隨筆檔案
2008年12月 (1)
2008年4月 (2)
2008年2月 (1)
2008年1月 (1)
2007年12月 (3)
2007年11月 (1)
2007年10月 (3)
2007年7月 (2)
2007年6月 (1)
2007年4月 (2)
2007年3月 (3)
2007年2月 (5)
2007年1月 (3)
2006年12月 (4)
文章分類
axis(6)
(rss)
eclipse(7)
(rss)
Hibernate(30)
(rss)
html/js/css(107)
(rss)
java(106)
(rss)
linux(7)
(rss)
Lucene(7)
(rss)
spring(36)
(rss)
Spring CLOUd(1)
(rss)
Strtus(30)
(rss)
其它(48)
(rss)
開源opensource(48)
(rss)
數(shù)據(jù)庫DateBase(30)
(rss)
設(shè)計模式(12)
(rss)
文章檔案
2018年8月 (1)
2012年5月 (1)
2012年4月 (2)
2011年7月 (6)
2010年3月 (1)
2010年2月 (1)
2010年1月 (3)
2009年12月 (1)
2009年10月 (1)
2009年8月 (3)
2009年3月 (1)
2009年2月 (1)
2008年12月 (3)
2008年11月 (10)
2008年10月 (3)
2008年9月 (2)
2008年8月 (2)
2008年7月 (4)
2008年6月 (13)
2008年5月 (15)
2008年4月 (9)
2008年3月 (10)
2008年1月 (18)
2007年12月 (33)
2007年11月 (6)
2007年10月 (18)
2007年9月 (10)
2007年8月 (18)
2007年7月 (15)
2007年6月 (25)
2007年5月 (19)
2007年4月 (26)
2007年3月 (38)
2007年2月 (33)
2007年1月 (27)
2006年12月 (27)
2006年11月 (12)
java
Ajax特效網(wǎng)站
cndiy nio
GRO
Hani Suleiman's blog
Java之路
java論壇
J道
mule
mule 入門
oksonic(動畫教程)
一路由你
中國eclipse
八進(jìn)制
在線源碼
多線程實戰(zhàn)
天火
小米的blogjava
幻境伯克----jface/swt
很全的博克-強(qiáng)
每日一得
滿江紅
邢紅瑞
飛翔
鳥詩選(js)
鳥食軒 (dhtml)
工具
apache中文手冊
extjs學(xué)習(xí)
iconFindre
java 安全
javaresearch
java技巧網(wǎng)
js之王
matrix(study)
prototype api
spring中文
北京IT企業(yè)速查
在線流程圖工具
雅虎翻譯
朋友
Happyshow
hibernate異常
skywalker
sunshow
xf
亞光
同云博客
小弟鵬
張玉磊
昕
李陽
黃鳴
搜索
積分與排名
積分 - 1101823
排名 - 28
最新評論
1.?re: hibernate.cfg.xml配置
好全啊 .. 棒棒噠 ~ !
--junqinag.yang
2.?re: Quartz任務(wù)調(diào)度快速入門
我現(xiàn)在來看還是覺得不錯
--小任
3.?re: js中this的總結(jié)
評論內(nèi)容較長,點擊標(biāo)題查看
--pam
4.?re: Quartz任務(wù)調(diào)度快速入門
樓主辛苦
--yd
5.?re: Quartz任務(wù)調(diào)度快速入門
頂了,內(nèi)容寫的很好
--sen
閱讀排行榜
1.?網(wǎng)頁不緩存(3553)
2.?Form嵌套引起的問題 (2852)
3.?解決IE下CSS背景圖片閃爍的Bug(2447)
4.?Spring AOP的動態(tài)載入原理(2406)
5.?如何制作漂亮的Excel表格(2046)
評論排行榜
1.?北京戶口--吃官司(5)
2.?開始→運行→輸入的命令集錦(3)
3.?讓網(wǎng)頁上的所有圖片動起來(2)
4.?Dom4j 編碼問題徹底解決 (1)
5.?心情不爽(1)
Powered by:
博客園
模板提供:
滬江博客
Copyright ©2025 大田斗
主站蜘蛛池模板:
午夜精品在线免费观看
|
国产四虎免费精品视频
|
久久免费精彩视频
|
亚洲人成在线免费观看
|
免费看美女让人桶尿口
|
亚洲国产精品成人一区
|
亚洲AV日韩AV永久无码免下载
|
亚洲欧洲日韩综合
|
亚洲AV无码AV吞精久久
|
9久热精品免费观看视频
|
一级毛片免费不卡在线
|
毛片免费在线观看网站
|
亚洲电影日韩精品
|
亚洲精品视频在线观看你懂的
|
免费国产成人午夜电影
|
亚洲午夜无码久久久久
|
亚洲成a人片7777
|
精品特级一级毛片免费观看
|
在线观看肉片AV网站免费
|
最刺激黄a大片免费网站
|
亚洲色大18成人网站WWW在线播放 亚洲色大成WWW亚洲女子
|
78成人精品电影在线播放日韩精品电影一区亚洲
|
亚洲AV永久青草无码精品
|
亚洲成人一级电影
|
国产成人综合亚洲绿色
|
精品免费视在线观看
|
思思99re66在线精品免费观看
|
亚洲人成无码网WWW
|
亚洲精品一区二区三区四区乱码
|
亚洲AV中文无码乱人伦在线视色
|
亚洲成人中文字幕
|
久久亚洲精品11p
|
爱丫爱丫影院在线观看免费
|
日韩成人在线免费视频
|
亚洲AV无码乱码在线观看富二代
|
亚洲一久久久久久久久
|
久操免费在线观看
|
国产一区二区三区免费看
|
精品亚洲成a人片在线观看
|
亚洲AV无码成人网站在线观看
|
野花香高清视频在线观看免费
|