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 大田斗
主站蜘蛛池模板:
无码人妻精品一二三区免费
|
亚洲色婷婷综合久久
|
亚洲精品第一国产综合精品
|
日韩色日韩视频亚洲网站
|
免费看的黄色大片
|
亚洲国产精品网站在线播放
|
日本成人在线免费观看
|
曰批免费视频播放免费
|
伊人久久大香线蕉亚洲五月天
|
免费h成人黄漫画嘿咻破解版
|
青草久久精品亚洲综合专区
|
免费少妇a级毛片
|
久久久久女教师免费一区
|
亚洲日韩欧洲乱码AV夜夜摸
|
日本不卡免费新一区二区三区
|
亚洲人成影院在线无码观看
|
h片在线观看免费
|
亚洲国产精品久久久久久
|
99爱在线精品免费观看
|
亚洲а∨精品天堂在线
|
亚洲人成电影网站国产精品
|
亚洲最大黄色网址
|
成人毛片免费在线观看
|
h在线看免费视频网站男男
|
亚洲成Av人片乱码色午夜
|
日本高清在线免费
|
精品国产亚洲第一区二区三区
|
丁香五月亚洲综合深深爱
|
91精品免费观看
|
亚洲精品无AMM毛片
|
综合亚洲伊人午夜网
|
中国一级毛片视频免费看
|
久久久久亚洲精品日久生情
|
看全色黄大色大片免费久久
|
国产免费毛不卡片
|
一区二区视频免费观看
|
亚洲国产高清在线精品一区
|
日批日出水久久亚洲精品tv
|
免费无码又爽又刺激网站
|
亚洲日韩精品A∨片无码加勒比
|
亚洲午夜国产精品无码
|