一、 填空題
1.處于運(yùn)行狀態(tài)的線程在某些情況下,如執(zhí)行了sleep(睡眠)方法,或等待I/O設(shè)備等資源,將讓出CPU并暫時(shí)停止自己的運(yùn)行,進(jìn)入____阻塞_____狀態(tài)。
2.處于新建狀態(tài)的線程被啟動(dòng)后,將進(jìn)入線程隊(duì)列排隊(duì)等待CPU,此時(shí)它已具備了運(yùn)行條件,一旦輪到享用CPU資源就可以獲得執(zhí)行機(jī)會(huì)。上述線程是處于 就緒 狀態(tài)。
解析: 線程的生命周期—五個(gè)階段
新建狀態(tài)---- new關(guān)鍵字創(chuàng)建線程對象
就緒狀態(tài)---- start()方法運(yùn)行之前
運(yùn)行狀態(tài)---- run()方法的運(yùn)行
堵塞狀態(tài)--- interrupt() sleep() join() yield() wait() 等方法
死亡狀態(tài)--- stop()方法(已過時(shí)) /或run()方法運(yùn)行結(jié)束
1.一個(gè)正在執(zhí)行的線程可能被人為地中斷,讓出CPU的使用權(quán),暫時(shí)中止自己的執(zhí)行,進(jìn)入 阻塞 狀態(tài)。
解析:人為的中斷正在執(zhí)行的線程---- 執(zhí)行wait() 、interrupt() 、sleep()方法等
1.在Java中編寫實(shí)現(xiàn)多線程應(yīng)用有兩種途徑:一種是繼承Thread類創(chuàng)建線程,另一種是實(shí)現(xiàn) Runnable 接口創(chuàng)建線程。
解析: 繼承Thread類來創(chuàng)建線程,不能實(shí)現(xiàn)資源的共享,除非資源使用static修飾。
實(shí)現(xiàn)Runnable接口創(chuàng)建線程,此時(shí)還需要借助Thread類,因?yàn)镽unnable接口
沒有start()方法,同時(shí)Thread類是Runnable接口的子類….
1.在線程控制中,可以調(diào)用_____join()____方法,阻塞當(dāng)前正在執(zhí)行的線程,等插隊(duì)線程執(zhí)行完后后再執(zhí)行阻塞線程。
2.多線程訪問某個(gè)共享資源可能出現(xiàn)線程安全問題,此時(shí)可以使用______synchronized_____關(guān)鍵字來實(shí)現(xiàn)線程同步,從而避免安全問題出現(xiàn),但會(huì)影響性能,甚至出現(xiàn)死鎖。
- 在線程通信中,調(diào)用wait( )可以是當(dāng)前線程處于等待狀態(tài),而為了喚醒一個(gè)等待的線程,需要調(diào)用的方法是____notify()/notifyAll()__________。
解析:線程等待使用wait()方法,此方法最先是存在于Object類,Thread類繼承Object類,可以獲取此方法,同時(shí)notify()方法和notifyAll()方法---線程喚醒,最先也是存在于
Object類當(dāng)中。
1.在線程通信中,可以調(diào)用wait()、notify()、notifyAll()三個(gè)方法實(shí)現(xiàn)線程通信,這三個(gè)方法都是____Object____類提供的public方法,所以任何類都具有這三個(gè)方法。
二、 選擇題
下列關(guān)于Java線程的說法正確的是( A )。(選擇一項(xiàng))
A
每一個(gè)Java線程可以看成由代碼、一個(gè)真實(shí)的CPU以及數(shù)據(jù)三部分組成
B.
創(chuàng)建線程的兩種方法中,從Thread類中繼承方式可以防止出現(xiàn)多父類的問題
C.
Thread類屬于java.util程序包
D.
使用new Thread(new X()).run();方法啟動(dòng)一個(gè)線程
解析:
A、語句正確。
B、創(chuàng)建線程兩種方法:一是繼承Thread類,一是實(shí)現(xiàn)Runnable接口
根據(jù)Java語言類的單繼承特性,防止出現(xiàn)多繼承,但是可以實(shí)現(xiàn)多
重繼承,也可以出現(xiàn)多父類。
C、Thread類是存在于java.lang包下
D、啟動(dòng)一個(gè)線程是調(diào)用start()方法,之后JVM會(huì)默認(rèn)的調(diào)用run()方法
run()方法是線程的主體,核心代碼放到此方法當(dāng)中。
以下選項(xiàng)中可以填寫到橫線處,讓代碼正確編譯和運(yùn)行的是( AD )。(選擇一項(xiàng))
public class Test implements Runnable {
public static void main(String[] args) {
___________________________________
t.start();
System.out.println("main");
}
public void run() {
System.out.println("thread1!");
}
}
A.
Thread t = new Thread(new Test());
B.
Test t = new Test();
C.
Thread t = new Test();
D.
Thread t = new Thread();
解析:
線程的創(chuàng)建有兩種方式,其中之一就是實(shí)現(xiàn)Runnable接口。
此接口只有一個(gè)抽象方法---run()方法,啟動(dòng)線程又需要start()方法
此時(shí)還需要借助Thread類,根據(jù)Thread類的構(gòu)造方法:
Public Thread(Runnable run)
需要傳入Runnable接口對象
此題還有一個(gè)方法: 直接創(chuàng)建Thread類對象,調(diào)用start()方法
所以D選項(xiàng)也是正確的,但是此題重點(diǎn)還是考的子類實(shí)現(xiàn)Runnable接口
根據(jù)Thread類的構(gòu)造方法啟動(dòng)線程。
如下代碼創(chuàng)建一個(gè)新線程并啟動(dòng)線程,問:四個(gè)選項(xiàng)中可以保證正確代碼創(chuàng)建target對象,并能編譯正確的是( C )?(選擇一項(xiàng))
public static void main(String[] args) {
Runnable target=new MyRunnable( );
Thread myThread=new Thread(target);
}
A
public class MyRunnable extends Runnable {
public void run( ) { }
}
B.
public class MyRunnable extends Runnable {
void run( ) { }
}
C.
public class MyRunnable implements Runnable {
public void run( ) { }
}
D.
public class MyRunnable implements Runnable {
void run( ) { }
解析:接口是用來實(shí)現(xiàn)的,不是繼承,所以AB兩個(gè)選項(xiàng)錯(cuò)誤。
根據(jù)Java多態(tài)機(jī)制,子類可以為父類(接口)實(shí)例化對象
根據(jù)子類實(shí)現(xiàn)接口的規(guī)則,子類必須重寫接口當(dāng)中的抽象方法
此時(shí)又復(fù)習(xí)到了方法重寫的規(guī)則:子類重寫的方法它的權(quán)限必須
大于等于父類方法權(quán)限(除去private外)。根據(jù)以上得出C是對的
當(dāng)線程調(diào)用start( )后,其所處狀態(tài)為( C )。(選擇一項(xiàng))
A
阻塞狀態(tài)
B.
運(yùn)行狀態(tài)
C.
就緒狀態(tài)
D.
新建狀態(tài)
解析:線程的五個(gè)狀態(tài)也就是它的生命周期:
新建狀態(tài)----通過new關(guān)鍵字來創(chuàng)建線程對象
就緒狀態(tài)----調(diào)用start()方法
運(yùn)行狀態(tài)----調(diào)用run()方法
阻塞狀態(tài)----調(diào)用sleep()、wait()、join() 、yield()、interrupt ()等方法
消亡狀態(tài)----調(diào)用stop()方法,但是此方法已經(jīng)過時(shí)。
下列關(guān)于Thread類提供的線程控制方法的說法中,錯(cuò)誤的是( C )。(選擇一項(xiàng))
A
線程A中執(zhí)行線程B的join()方法,則線程A等待直到B執(zhí)行完成
B.
線程A通過調(diào)用interrupt()方法來中斷其阻塞狀態(tài)
C.
若線程A調(diào)用方法isAlive()返回值為false,則說明A正在執(zhí)行中,也可能是可運(yùn)行狀態(tài)
D.
currentThread()方法返回當(dāng)前線程的引用
解析:
A: join()方法—強(qiáng)制加入,加入的線程執(zhí)行完畢之后才能執(zhí)行其他線程
B:interrupt()方法---線程中斷,題中的說法有些牽強(qiáng)
C:isAlive()方法---判斷一個(gè)線程是否在活動(dòng),如果在活動(dòng)返回真,反之假
D:currentThread()方法返回正在執(zhí)行的線程
從以上得知,C明顯錯(cuò)誤。
下列關(guān)于線程的優(yōu)先級說法中,正確的是( BD )。(選擇兩項(xiàng))
A
線程的優(yōu)先級是不能改變的
B.
線程的優(yōu)先級是在創(chuàng)建線程時(shí)設(shè)置的
C.
在創(chuàng)建線程后的任何時(shí)候都可以重新設(shè)置
D.
線程的優(yōu)先級的范圍在1-10之間
解析:線程的優(yōu)先級可以通過setPriority(int newPriority)的方法進(jìn)行設(shè)置
線程一共有三個(gè)優(yōu)先級,分別是:最低優(yōu)先級(1) 中等優(yōu)先級(5)
最高優(yōu)先級(10),咱們經(jīng)常寫的main方法就是中等優(yōu)先級線程。
A:線程的優(yōu)先級是可以更改也可以獲取,但是有一點(diǎn),即使設(shè)置為最高
優(yōu)先級也不一定先執(zhí)行,只是它優(yōu)先執(zhí)行的幾率比較高。
B:線程的優(yōu)先級是在創(chuàng)建時(shí)進(jìn)行設(shè)置,通過setPriority()方法設(shè)置
C:正在執(zhí)行的線程是不允許重新設(shè)置線程優(yōu)先級的。
D:線程的優(yōu)先級范圍是1—10 符合要求
以下選項(xiàng)中關(guān)于Java中線程控制方法的說法正確的是( AD )。(選擇二項(xiàng))
A.
join ( ) 的作用是阻塞指定線程等到另一個(gè)線程完成以后再繼續(xù)執(zhí)行
B.
sleep ( ) 的作用是讓當(dāng)前正在執(zhí)行線程暫停,線程將轉(zhuǎn)入就緒狀態(tài)
C.
yield ( ) 的作用是使線程停止運(yùn)行一段時(shí)間,將處于阻塞狀態(tài)
D.
setDaemon( )的作用是將指定的線程設(shè)置成后臺(tái)線程
解析:
A:join()方法—線程的強(qiáng)制加入,加入的線程執(zhí)行完畢之后再執(zhí)行其他線程
B:sleep()方法—線程休眠,等時(shí)間過時(shí),線程處于運(yùn)行狀態(tài)
C:yield()方法—線程禮讓,讓出CUP資源,其他線程先執(zhí)行,有些與join()
方法類似
D:setDaemon()方法--將指定的線程設(shè)置成后臺(tái)線程,對的。
題的答案是:AD,但是個(gè)人感覺C選項(xiàng)也是對的……
在多個(gè)線程訪問同一個(gè)資源時(shí),可以使用( A )關(guān)鍵字來實(shí)現(xiàn)線程同步,保證對資源安全訪問。(選擇一項(xiàng))
A.
Synchronized
B.
Transient
C.
Static
D.
Yield
解析:關(guān)于同步,有兩種實(shí)現(xiàn)方式,一種是同步方法,一種是同步代碼塊
無論怎樣,都需要使用到synchronized關(guān)鍵字。
同步方法:
權(quán)限修飾符 synchronized 返回值類型 方法名稱(參數(shù)列表){
N行代碼;
}
同步代碼塊:
Synchronized(對象){
N行代碼;
}
Java中線程安全問題是通過關(guān)鍵字( C )解決的?。(選擇一項(xiàng))
A.
Finally
B.
wait( )
C.
Synchronized
D.
notify( )
以下說法中關(guān)于線程通信的說法錯(cuò)誤的是( D )?。(選擇一項(xiàng))
A.
可以調(diào)用wait()、notify()、notifyAll()三個(gè)方法實(shí)現(xiàn)線程通信
B.
wait()、notify()、notifyAll()必須在synchronized方法或者代碼塊中使用
C.
wait()有多個(gè)重載的方法,可以指定等待的時(shí)間
D.
wait()、notify()、notifyAll()是Object類提供的方法,子類可以重寫
解析:
A選項(xiàng):
在線程通信中,可以調(diào)用wait()、notify()、notifyAll()三個(gè)方法實(shí)現(xiàn)線程通信,這三個(gè)方法都是Object類提供的public方法,所以任何類都具有這三個(gè)方法。
B選項(xiàng):在編程題的第二題當(dāng)中,wait()方法、notify()方法、notifyAll()方法都是寫在同步方法當(dāng)中,具體可以查看此類的源碼。
C選項(xiàng):Object類當(dāng)中的wait方法的重載如下:
public final void wait()
public final void wait(long timeout)
public final void wait(long timeout, int nanos)
三個(gè)方法都拋出異常-- InterruptedException
D選項(xiàng) : 看A選項(xiàng)的解釋
以上三個(gè)方法都使用final修飾,所以子類是不能重寫的
三、 判斷題
1.進(jìn)程是線程Thread內(nèi)部的一個(gè)執(zhí)行單元,它是程序中一個(gè)單一順序控制流程。( × )
解析:線程是進(jìn)程的一個(gè)執(zhí)行單位,進(jìn)程包含線程。
1.Thread類實(shí)現(xiàn)了Runnable接口。( √ )
解析:Thread類在JDK當(dāng)中的定義如下:
Public class Thread extends Object implements Runnable
從定義可知,它是Runnable接口的子類。
1.一個(gè)進(jìn)程可以包括多個(gè)線程。兩者的一個(gè)主要區(qū)別是:線程是資源分配的單位,而進(jìn)程CPU調(diào)度和執(zhí)行的單位。( × )
解析:不管是進(jìn)程還是線程,都是通過循環(huán)獲得自己執(zhí)行的時(shí)間片,獲得CUP資源。
1.用new關(guān)鍵字建立一個(gè)線程對象后,該線程對象就處于新生狀態(tài)。處于新生狀態(tài)的線程有自己的內(nèi)存空間,通過調(diào)用start進(jìn)入就緒狀態(tài)。( √ )
解析:具體解析看選擇題第四題的解釋。
1.A線程的優(yōu)先級是10,B線程的優(yōu)先級是1,那么當(dāng)進(jìn)行調(diào)度時(shí)一定會(huì)先調(diào)用A( × )
解析:線程的執(zhí)行,不是誰的優(yōu)先級高就先執(zhí)行,只是它的概率會(huì)高。
1.線程可以用yield使低優(yōu)先級的線程運(yùn)行。( × )
解析:yield()方法是線程禮讓,可以讓出自己執(zhí)行其他線程,由于線程的執(zhí)行存在嚴(yán)重
的隨機(jī)性,不能確定使低優(yōu)先級的線程執(zhí)行。
1.Thread.sleep( )方法調(diào)用后,當(dāng)?shù)却龝r(shí)間未到,該線程所處狀態(tài)為阻塞狀態(tài)。當(dāng)?shù)却龝r(shí)間已到,該線程所處狀態(tài)為運(yùn)行狀態(tài)。( √ )
解析:sleep()方法是線程休眠,處于阻塞狀態(tài),當(dāng)時(shí)間一到,就會(huì)執(zhí)行處于運(yùn)行狀態(tài)。
如果真要追究用詞的嚴(yán)謹(jǐn)性,應(yīng)該不是”等待時(shí)間”,而是”休眠時(shí)間”。
1.當(dāng)一個(gè)線程進(jìn)入一個(gè)對象的一個(gè)synchronized方法后,其它線程不可以再進(jìn)入該對象同步的其它方法執(zhí)行。( √ )
解析:對的,可以查看一下編程題第二題的源碼。
1.wait方法被調(diào)用時(shí),所在線程是會(huì)釋放所持有的鎖資源, sleep方法不會(huì)釋放。( √ )
解析:sleep 是線程類(Thread)的方法,導(dǎo)致此線程暫停執(zhí)行指定時(shí)間,給執(zhí)行機(jī)會(huì)給其他線程,但是監(jiān)控狀態(tài)依然保持,到時(shí)后會(huì)自動(dòng)恢復(fù),所以調(diào)用sleep 不會(huì)釋放對象鎖。
wait 是Object 類的方法,對此對象調(diào)用wait 方法導(dǎo)致本線程放棄對象鎖,進(jìn)入等待此對象的等待鎖定池,只有針對此對象發(fā)出notify 方法(或notifyAll)后本線程才進(jìn)入對象鎖定池準(zhǔn)備獲得對象鎖進(jìn)入運(yùn)行狀態(tài)。
1.wait、notify、notifyAll是在Object類中定義的方法。( √ )
解析:具體可以查看API幫助文檔,查看。
1.notify是喚醒所在對象wait pool中的第一個(gè)線程。( × )
解析:喚醒的不一定是第一個(gè)線程。
JDK已經(jīng)明確說明喚醒哪個(gè)thread是隨意決定的,沒有特定順序
The choice is arbitrary and occurs at the discretion of the implementation
四、 簡答題
1.簡述程序、進(jìn)程和線程的聯(lián)系和區(qū)別。
2.創(chuàng)建線程的兩種方式分別是什么?各有什么優(yōu)缺點(diǎn)。
3.sleep、yield、join方法的區(qū)別?
4.synchronize修飾的語句塊,如下面的代碼。是表示該代碼塊運(yùn)行時(shí)必須獲得account對象的鎖。如果沒有獲得,會(huì)有什么情況發(fā)生?
synchronized (account) {
if(account.money-drawingNum<0){
return;
}
}
1.請你簡述sleep( )和wait( )有什么區(qū)別?
2.死鎖是怎么造成的?用文字表達(dá)。再寫一個(gè)代碼示例。
3.Java中實(shí)現(xiàn)線程通信的三個(gè)方法及其作用。
4.為什么不推薦使用stop和destroy方法來結(jié)束線程的運(yùn)行?
五、 編碼題
1.設(shè)計(jì)一個(gè)多線程的程序如下:設(shè)計(jì)一個(gè)火車售票模擬程序。假如火車站要有100張火車票要賣出,現(xiàn)在有5個(gè)售票點(diǎn)同時(shí)售票,用5個(gè)線程模擬這5個(gè)售票點(diǎn)的售票情況。
public class CharPrint extends Thread
{
// 定義屬性
private Printer p;
//構(gòu)造方法
public CharPrint(Printer p)
{
super();
this.p = p;
}
//重寫run()方法
public void run()
{
char c = 'A';//定義起始位置
//通過for循環(huán)對其進(jìn)行輸出
while (c <= 'Z')
{
p.print(c);
c++;//控制while循環(huán)當(dāng)中的條件表達(dá)式
}
}
}
public class NumberPrint extends Thread
{
//定義屬性
private Printer p;
//構(gòu)造方法
public NumberPrint(Printer p)
{
this.p = p;
}
//重寫run()方法
public void run()
{
int i = 1;//定義起始位置
while (i <= 52)
{
p.print(i);
i++;//控制while循環(huán)當(dāng)中的條件表達(dá)式
}
}
}
public class Printer
{
//定義一個(gè)int類型變量---用于計(jì)數(shù)
int index = 1;
//同步的方法---print()
public synchronized void print(int i)
{
//判斷是否是3的倍數(shù)
while (index % 3 == 0)
{
try
{
wait();//線程等待
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//打印輸出數(shù)字
System.out.print("" + i);
//控制while循環(huán)中的條件表達(dá)式
index++;
//線程喚醒
notifyAll();
}
public synchronized void print(char c)
{
//判斷是否是3的倍數(shù)
while (index % 3 != 0)
{
try
{
wait();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//打印字母
System.out.print("" + c);
//控制while循環(huán)中的條件表達(dá)式
index++;
//喚醒線程
notifyAll();
}
}
public class Test
{
public static void main(String[] args)
{
//創(chuàng)建Printer對象,為NumberPrint()類構(gòu)造方法做準(zhǔn)備
Printer p = new Printer();
//創(chuàng)建線程---子類為父類實(shí)例化對象
Thread t1 = new NumberPrint(p);
Thread t2 = new CharPrint(p);
//啟動(dòng)線程
t1.start();
t2.start();
}
}
2.編寫兩個(gè)線程,一個(gè)線程打印1-52的整數(shù),另一個(gè)線程打印字母A-Z。打印順序?yàn)?2A34B56C….5152Z。即按照整數(shù)和字母的順序從小到大打印,并且每打印兩個(gè)整數(shù)后,打印一個(gè)字母,交替循環(huán)打印,直到打印到整數(shù)52和字母Z結(jié)束。
要求:
編寫打印類Printer,聲明私有屬性index,初始值為1,用來表示是第幾次打印。在打印類Printer中編寫打印數(shù)字的方法print(int i),3的倍數(shù)就使用wait()方法等待,否則就輸出i,使用notifyAll()進(jìn)行喚醒其它線程。在打印類Printer中編寫打印字母的方法print(char c),不是3的倍數(shù)就等待,否則就打印輸出字母c,使用notifyAll()進(jìn)行喚醒其它線程。編寫打印數(shù)字的線程N(yùn)umberPrinter繼承Thread類,聲明私有屬性private Printer p;在構(gòu)造方法中進(jìn)行賦值,實(shí)現(xiàn)父類的run方法,調(diào)用Printer類中的輸出數(shù)字的方法。編寫打印字母的線程LetterPrinter繼承Thread類,聲明私有屬性private Printer p;在構(gòu)造方法中進(jìn)行賦值,實(shí)現(xiàn)父類的run方法,調(diào)用Printer類中的輸出字母的方法。編寫測試類Test,創(chuàng)建打印類對象,創(chuàng)建兩個(gè)線程類對象,啟動(dòng)線程。
public class TicketSalSystem implements Runnable
{
// 定義變量---票數(shù)/票號
public int ticket = 100;
public int count = 0;
// 重寫run()方法
public void run()
{
// 定義while循環(huán), 循環(huán)售票
while (ticket > 0)
{
// 根據(jù)題的要求,實(shí)現(xiàn)同步,此時(shí)定義同步代碼塊
synchronized (this)
{// 傳入對象,使用this代替當(dāng)前類對象
// 判斷是否還有票,如果大于零說明還有票可賣
if (ticket > 0)
{
// 線程休眠0.5秒
try
{
Thread.sleep(500);
} catch (InterruptedException e)
{
e.printStackTrace();
}
count++; // 票號++
ticket--;// 循環(huán)售票,賣一張少一張
// 輸出當(dāng)前的售票窗口和票號
System.out.println(Thread.currentThread().getName()
+ "\t當(dāng)前票號:" + count);
}
}
}
}
}
public class TicketTest
{
public static void main(String[] args)
{
// 創(chuàng)建線程類對象
TicketSalSystem st = new TicketSalSystem();
// 啟動(dòng)5次線程
for (char i = 'A'; i <= 'F'; i++)
{
/*
* 創(chuàng)建匿名Thread類對象
* 1、根據(jù)Thread類構(gòu)造方法,傳入Runnable接口對象
* TicketSalSystem類是Runnable接口的子類,子類對象st可以讓父類接收
* 2、Thread類的構(gòu)造方法如下:
* public Thread(Runnable run,String name)
* 在創(chuàng)建線程的同時(shí),為線程名稱
* 3、啟動(dòng)線程是使用start方法,啟動(dòng)之后JVM會(huì)默認(rèn)的區(qū)調(diào)用run()方法
*/
new Thread(st, "售票口" + i).start();
}
}
}
六、 可選題
1.設(shè)計(jì)4個(gè)線程,其中兩個(gè)線程每次對j增加1,另外兩個(gè)線程對j每次減少1。
要求:使用內(nèi)部類實(shí)現(xiàn)線程,對j增減的時(shí)候不考慮順序問題。
public class ThreadTest61
{
//聲明成員變量j
private int j;
public static void main(String[] args)
{
//創(chuàng)建ThreadTest61的對象
ThreadTest61 tt = new ThreadTest61();
//創(chuàng)建內(nèi)部線程類對象
Inc inc = tt.new Inc();
Dec dec = tt.new Dec();
for (int i = 0; i < 2; i++)
{
// 創(chuàng)建線程對象,啟動(dòng)線程
Thread t = new Thread(inc);
t.start();
// 創(chuàng)建線程對象,啟動(dòng)線程
t = new Thread(dec);
t.start();
}
}
//實(shí)現(xiàn)同步對j的值加
private synchronized void inc()
{
//調(diào)用此方法一次,對j就增加一次
j++;
System.out.println(Thread.currentThread().getName() + "-inc:" + j);
}
//實(shí)現(xiàn)同步對j的值減
private synchronized void dec()
{
//調(diào)用此方法一次,對j就減一次
j--;
System.out.println(Thread.currentThread().getName() + "-dec:" + j);
}
//內(nèi)部類實(shí)現(xiàn)Runnable接口,重寫run()方法
class Inc implements Runnable
{
public void run()
{
//for循環(huán)當(dāng)中調(diào)用inc()方法,實(shí)現(xiàn)每次對j加1
for (int i = 0; i < 100; i++)
{
//調(diào)用加的方法
inc();
}
}
}
//內(nèi)部類實(shí)現(xiàn)Runnable接口,重寫run()方法
class Dec implements Runnable
{
public void run()
{
//for循環(huán)當(dāng)中調(diào)用inc()方法,實(shí)現(xiàn)每次對j減1
for (int i = 0; i < 100; i++)
{
//調(diào)用減的方法
dec();
}
}
}
}
2.編寫多線程程序,模擬多個(gè)人通過一個(gè)山洞的模擬。這個(gè)山洞每次只能通過一個(gè)人,每個(gè)人通過山洞的時(shí)間為5秒,有10個(gè)人同時(shí)準(zhǔn)備過此山洞,顯示每次通過山洞人的姓名和順序。
public class ThreadTest62
{
public static void main(String[] args)
{
/*創(chuàng)建一個(gè)山洞對象,為Thread類構(gòu)造方法做準(zhǔn)備
* public Thread(Runnable run,String name)
*/
Tunnel tul = new Tunnel();
//創(chuàng)建十個(gè)過山洞線程,并為線程命名
Thread p1 = new Thread(tul, "p1");
Thread p2 = new Thread(tul, "p2");
Thread p3 = new Thread(tul, "p3");
Thread p4 = new Thread(tul, "p4");
Thread p5 = new Thread(tul, "p5");
Thread p6 = new Thread(tul, "p6");
Thread p7 = new Thread(tul, "p7");
Thread p8 = new Thread(tul, "p8");
Thread p9 = new Thread(tul, "p9");
Thread p10 = new Thread(tul, "p10");
//啟動(dòng)十個(gè)線程
p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
p6.start();
p7.start();
p8.start();
p9.start();
p10.start();
}
}
//創(chuàng)建山洞類并實(shí)現(xiàn)Runnable接口,重寫run()方法
class Tunnel implements Runnable
{
//定義變量,初始化過山洞人數(shù)
int crossedNum = 0;
//重寫run()方法,在此方法當(dāng)中調(diào)用cross()方法
public void run()
{
cross();
}
//定義過山洞的同步方法
public synchronized void cross()
{
//每個(gè)人通過山洞的時(shí)間為5秒
try
{
Thread.sleep(5000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
//人數(shù)統(tǒng)計(jì),過一個(gè)人增加一個(gè)人
crossedNum++;
//顯示每次通過山洞人的姓名
System.out.println(Thread.currentThread().getName()
+ "通過了山洞,這是第" + crossedNum + "個(gè)用戶");
}
}