Java程序設(shè)計應(yīng)用開發(fā)教程 課件 單元7 網(wǎng)絡(luò)編程與多線程_第1頁
Java程序設(shè)計應(yīng)用開發(fā)教程 課件 單元7 網(wǎng)絡(luò)編程與多線程_第2頁
Java程序設(shè)計應(yīng)用開發(fā)教程 課件 單元7 網(wǎng)絡(luò)編程與多線程_第3頁
Java程序設(shè)計應(yīng)用開發(fā)教程 課件 單元7 網(wǎng)絡(luò)編程與多線程_第4頁
Java程序設(shè)計應(yīng)用開發(fā)教程 課件 單元7 網(wǎng)絡(luò)編程與多線程_第5頁
已閱讀5頁,還剩28頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

單元7

網(wǎng)絡(luò)編程與多線程7.1網(wǎng)絡(luò)編程程序設(shè)計

任務(wù)7.1單用戶登錄任務(wù)描述用戶登錄KFID自動出貨管理系統(tǒng),需要在服務(wù)器與客戶端之間進(jìn)行通信,效果如圖7-1所示。當(dāng)?shù)谝粋€客戶(即用戶)登錄系統(tǒng)時,從客戶端發(fā)起登錄請求,客戶端將數(shù)據(jù)傳遞到服務(wù)器,由服務(wù)器顯示用戶登錄信息,并響應(yīng)給客戶端登錄信息的情況;當(dāng)?shù)谝粋€客戶與服務(wù)器進(jìn)行通信時,其他客戶必須等待,只有第一個客戶退出,服務(wù)器才能與下一個客戶進(jìn)行通信,以此類推。圖7-1單用戶登錄服務(wù)器客戶端知識目標(biāo)了解IP地址和TCP協(xié)議。理解InetAddress類。能力目標(biāo)能接收和發(fā)送Socket信息。能使用I/O流套接字進(jìn)行數(shù)據(jù)傳輸。素養(yǎng)目標(biāo)培養(yǎng)人文精神和法治意識。培養(yǎng)嚴(yán)謹(jǐn)?shù)墓ぷ髯黠L(fēng)和創(chuàng)新精神。任務(wù)7.1單用戶登錄當(dāng)一臺計算機(jī)向另一臺計算機(jī)通信時,需要知道另一臺計算機(jī)的地址。

互聯(lián)網(wǎng)協(xié)議(InternetProtocol,簡稱:IP)地址可以用來唯一標(biāo)識互聯(lián)網(wǎng)上的計算機(jī)。IP地址就好像門牌號碼,可以指定特定的地方,就像是“致能大道1號”。IPV4是由4個字節(jié)組成,也就是分為4個8位的二進(jìn)制,每8位之間用點(diǎn)隔開,每個8位整數(shù)可以轉(zhuǎn)換成一個0~255的十進(jìn)制整數(shù)。IPV6是由16個字節(jié)(128位)組成,寫成8個無符號整數(shù),每個整數(shù)用4個16進(jìn)制位表示,整數(shù)之間用冒號(:)分開,如3ffe:3201:1401:1280:c8ff:fe4d:db39:1984。IP地址有兩種分類方式:IPV4和IPV6。IP地址映射被稱為域名(domainname)

相關(guān)知識TCP協(xié)議互聯(lián)網(wǎng)協(xié)議是在互聯(lián)網(wǎng)中從一臺計算機(jī)向另一臺計算機(jī)以包的形式傳輸數(shù)據(jù)的一種低層協(xié)議。傳輸協(xié)議(TransmisssionControlProtocol,TCP)和用戶數(shù)據(jù)報協(xié)議(UserDatagramProtocol,UDP)。TCP協(xié)議能夠讓兩臺主機(jī)建立連接并交換數(shù)據(jù)流。它確保數(shù)據(jù)的傳送,也可確保數(shù)據(jù)包以它們發(fā)送的順序傳送。TCP端口是一個16位的整數(shù),用來指定正在計算機(jī)上運(yùn)行的進(jìn)程(或程序),也就是表示數(shù)據(jù)信息由哪個程序的服務(wù)器處理,它能夠讓用戶連接到服務(wù)器上各種不同的應(yīng)用程序。不同的進(jìn)程有不同的端口號,端口號可以從0~65535,從0~1023的端口號是保留給HTTP、FTP、SMTP等。如網(wǎng)頁服務(wù)器(HTTP)的端口號是80,InetAddress類是Java對IP地址的封裝,在中有許多類都使用到了InetAddress,包括ServerSocket,Socket,DatagramSocket等等。InetAddress類InetAddress類方法方法說明publicstaticInetAddress[]getAllByName(Stringhost)該方法可以從DNS上得到域名對應(yīng)的所有的IP。這個方法返回一個InetAddress類型的數(shù)組。publicstaticInetAddressgetByAddress(byte[]addr)該方法獲得網(wǎng)絡(luò)主機(jī)中具有指導(dǎo)IP地址的InetAddress對象。publicstaticInetAddressgetByAddress(Stringhost,byte[]addr)該方法通過IP地址來創(chuàng)建InetAddress對象,而且IP地址必須是byte數(shù)組形式,host只是一個用于表示addr的別名publicstaticInetAddressgetByName(Stringhost)該方法以通過指定域名從DNS中得到相應(yīng)的IP地址publicstaticInetAddressgetLocalHost()該方法可以得到描述本機(jī)IP的InetAddress對象示例:獲取本地主機(jī)的域名與IP地址import.InetAddress;public

classAddress{public

static

voidmain(String[]args){InetAddressinetAddr=null;//創(chuàng)建一個InetAddress對象try{ inetAddr=InetAddress.getLocalHost();//實(shí)例化InetAddress對象Stringcanonical=

inetAddr.getCanonicalHostName();//獲得本地主機(jī)的域名

StringhostName=inetAddr.getHostName();//獲得主機(jī)名Stringaddress=

inetAddr.getHostAddress();//獲得本機(jī)的IP地址

System.out.println("域名:"+canonical);System.out.println("主機(jī)名:"+hostName);System.out.println("IP地址:"+address);}catch(Exceptione){e.printStackTrace();}

}}Socket類.Socket類代表客戶端和服務(wù)器都用來互相溝通的套接字??蛻舳艘@取一個Socket對象通過實(shí)例化,而服務(wù)器獲得一個Socket對象則通過accept()方法的返回值。Socket類構(gòu)造方法構(gòu)造方法說明publicSocket(Stringhost,intport)throwsUnknownHostException,IOException創(chuàng)建一個流套接字并將其連接到指定主機(jī)上的指定端口號publicSocket(InetAddresshost,intport)throwsIOException創(chuàng)建一個流套接字并將其連接到指定IP地址的指定端口號。publicSocket(Stringhost,intport,InetAddresslocalAddress,intlocalPort)throwsIOException創(chuàng)建一個套接字并將其連接到指定遠(yuǎn)程主機(jī)上的指定遠(yuǎn)程端口。publicSocket(InetAddresshost,intport,InetAddresslocalAddress,intlocalPort)throwsIOException創(chuàng)建一個套接字并將其連接到指定遠(yuǎn)程地址上的指定遠(yuǎn)程端口publicSocket()通過系統(tǒng)默認(rèn)類型的SocketImpl創(chuàng)建未連接套接字Socket類Socket類的常用方法方法說明publicvoidconnect(SocketAddresshost,inttimeout)throwsIOException將此套接字連接到服務(wù)器,并指定一個超時值。publicInetAddressgetInetAddress()返回套接字連接的地址publicintgetPort()返回此套接字連接到的遠(yuǎn)程端口。publicintgetLocalPort()返回此套接字綁定到的本地端口。publicSocketAddressgetRemoteSocketAddress()返回此套接字連接的端點(diǎn)的地址,如果未連接則返回null。publicInputStreamgetInputStream()throwsIOException返回此套接字的輸入流publicOutputStreamgetOutputStream()throwsIOException返回此套接字的輸出流。publicvoidclose()throwsIOException關(guān)閉此套接字ServerSocket類服務(wù)器應(yīng)用程序通過使用.ServerSocket類以獲取一個端口,并且偵聽客戶端請求。ServerSocket類構(gòu)造方法構(gòu)造方法說明publicServerSocket(intport)throwsIOException創(chuàng)建綁定到特定端口的服務(wù)器套接字。publicServerSocket(intport,intbacklog)throwsIOException利用指定的backlog創(chuàng)建服務(wù)器套接字并將其綁定到指定的本地端口號。publicServerSocket(intport,intbacklog,InetAddressaddress)throwsIOException使用指定的端口、偵聽backlog和要綁定到的本地IP地址創(chuàng)建服務(wù)器。publicServerSocket()throwsIOException創(chuàng)建非綁定服務(wù)器套接字。ServerSocket類ServerSocket類的常用方法方法說明publicintgetLocalPort()返回此套接字在其上偵聽的端口。publicSocketaccept()throwsIOException偵聽并接受到此套接字的連接。publicvoidsetSoTimeout(inttimeout)通過指定超時值啟用/禁用SO_TIMEOUT,以毫秒為單位。publicvoidbind(SocketAddresshost,intbacklog)將ServerSocket綁定到特定地址(IP地址和端口號)。使用Socket實(shí)現(xiàn)網(wǎng)絡(luò)通信連接

建立socket連接來連接服務(wù)器。傳送

用戶發(fā)送信息到服務(wù)器。接受

用戶從服務(wù)器接受信息。要使客戶端能夠正常工作,必須要做好3個任務(wù):案例:服務(wù)器程序與客戶端一對一通信編寫一個客戶端程序和一個服務(wù)器程序,服務(wù)器端只向客戶端輸出“Helloworld”。分析:服務(wù)器程序(HelloServer.java)第一步:聲明一個ServerSocket對象,聲明一個PrintWriter對象,用于向客戶端打印輸出。ServerSocketserversocket=null;PrintWriterout=null;第二步:實(shí)例化ServerSocket對象,在9999端口進(jìn)行監(jiān)聽。

serversocket=newServerSocket(9999);第三步:聲明一個Socket對象clientsocket,此對象用于接收客戶端的Socket連接。然后通過ServerSocket類中的accept()方法,接收客戶端的Socket請求,此方法返回一個客戶端的Socket請求。

clientsocket=serversocket.accept();第四步:通過客戶端的Socket對象去實(shí)例化PrintWriter對象,此時out對象具備向客戶端打印信息的能力。調(diào)用println()方法,將信息打印至客戶端。out=newPrintWriter(clientsocket.getOutputStream(),true);out.println("Helloworld");第五步:分別關(guān)閉客戶端Socket連接,服務(wù)器端Socket連接。

clientsocket.close();serversocket.close();案例:服務(wù)器程序與客戶端一對一通信客戶端程序(HelloClient.java)第一步:聲明一個Socket對象,聲明一個BufferedReader對象in,此對象用于讀取服務(wù)器發(fā)送過來的數(shù)據(jù)。

Sockethellosocket=null;BufferedReaderin=null;第二步:用輸入輸出流與Socket關(guān)聯(lián)。首先實(shí)例化hellosocket對象,此連接在本機(jī)的9999端口上監(jiān)聽。然后通過hellosocket對象實(shí)例化BufferedReader對象。hellosocket=newSocket("localhost",9999);in=newBufferedReader(newInputStreamReader(hellosocket.getInputStream()));第三步:等待服務(wù)器端發(fā)送過來的信息并打印。System.out.println(in.readLine());第四步:關(guān)閉BufferedReader對象;關(guān)閉Socket對象。in.close();hellosocket.close();如果要需要服務(wù)器與多個客戶端通信,如何實(shí)現(xiàn)呢?可以通過線程來處理不同客戶發(fā)送的信息。單元7

網(wǎng)絡(luò)編程與多線程7.2多線程程序設(shè)計

任務(wù)7.2多用戶登錄任務(wù)描述多個用戶登錄自動出貨管理系統(tǒng),需要在服務(wù)器與多個客戶端之間進(jìn)行通信,效果如圖7-2所示。多線程是Java的一個重要特性。在服務(wù)器啟用多線程模式時,可以通過線程來處理不同用戶發(fā)送的信息。當(dāng)每個用戶登錄時,從客戶端發(fā)起登錄請求,將登錄用戶數(shù)據(jù)傳遞到服務(wù)器,由服務(wù)器顯示用戶登錄信息,并將信息響應(yīng)給客戶端(登錄成功或登錄失?。?。當(dāng)有多個客戶端連接到服務(wù)器時,服務(wù)器會為每個客戶端建立一個線程來處理接收到信息,而不會產(chǎn)生阻塞,實(shí)現(xiàn)一個服務(wù)器與多個客戶端的通信。圖7-2多用戶登錄知識目標(biāo)了解線程與進(jìn)程的區(qū)別。熟悉實(shí)現(xiàn)多線程的方法。熟悉線程同步的方法。能力目標(biāo)能通過繼承Thread類實(shí)現(xiàn)多線程。能通過Runnable接口實(shí)現(xiàn)多線程。能使用方法或代碼塊實(shí)現(xiàn)線程同步。能使用多線程和套接字實(shí)現(xiàn)服務(wù)器服務(wù)多個客戶的操作。素養(yǎng)目標(biāo)良好的職業(yè)道德規(guī)范。培養(yǎng)嚴(yán)謹(jǐn)?shù)墓ぷ髯黠L(fēng)和創(chuàng)新精神。任務(wù)7.2多用戶登錄在高速公路收費(fèi)匝道上,經(jīng)常會看到排成長龍的車隊(duì)。如果讓你來緩解這一擁塞的交通狀況,你的方案是什么?在一個行政收費(fèi)大廳里,如果只有一個辦事窗ロ,等待辦事的客戶很多。解決方案是?進(jìn)程可以理解為一個應(yīng)用程序的執(zhí)行過程,應(yīng)用程序一旦執(zhí)行,就是一個進(jìn)程。如果把進(jìn)程比作一個收費(fèi)站,多個收費(fèi)匝道就可以比作線程。如果將行政大廳比喻為一個進(jìn)程,每個辦事窗口就是一個線程。

相關(guān)知識多線程:多線程在Windows操作系統(tǒng)中的運(yùn)行進(jìn)程1進(jìn)程3線程1線程3線程2線程5線程4線程n…進(jìn)程2在CPU執(zhí)行進(jìn)程2的時間片內(nèi)圖7-3多線程在Windows操作系統(tǒng)中的運(yùn)行模式Windows操作系統(tǒng)是多任務(wù)操作系統(tǒng),它以進(jìn)程為單位。每個獨(dú)立執(zhí)行的程序都被稱為進(jìn)程。比如:正在運(yùn)行的QQ是一個進(jìn)程、正在運(yùn)行的企業(yè)微信是一個進(jìn)程,正在運(yùn)行的Eclipse也是一個進(jìn)程,每個進(jìn)程都可以包含多個線程。系統(tǒng)可以分配給每個進(jìn)程一段使用CPU的時間(也可以稱為CPU時間片),CPU在這段時間中執(zhí)行某個進(jìn)程(同理,同一個進(jìn)程種每個線程也可以得到一小段執(zhí)行時間,這樣一個進(jìn)程就可以具有多個并非執(zhí)行的線程),然后下一個CPU時間片又執(zhí)行另一個進(jìn)程。進(jìn)程是并發(fā)執(zhí)行程序在執(zhí)行過程中資源分配和管理的基本單位(資源分配的最小單位),每個進(jìn)程都有自己獨(dú)立的地址空間。線程是比進(jìn)程更小的執(zhí)行單元,是進(jìn)程中的一個實(shí)體,是被系統(tǒng)獨(dú)立調(diào)度和分派的基本單位。一個進(jìn)程在執(zhí)行過程中,可以產(chǎn)生多個線程。同一類線程共享代碼和數(shù)據(jù)空間,每個線程有獨(dú)立的運(yùn)行棧和程序計數(shù)器(PC),線程切換開銷小。多線程的機(jī)制則指可以同時運(yùn)行多個程序塊(進(jìn)程的多條路徑),在Java中被稱為并發(fā)機(jī)制。采用多線程機(jī)制可以是計算機(jī)資源得到更充分的使用,多線程可以使程序在同一時間內(nèi)完成很多任務(wù)操作。進(jìn)程與線程的概念classTestThread{

public

voidrun(){

for(int

i=0;i<5;++i){System.out.println("TestThread在運(yùn)行"

);

}

}}public

classMainClass{public

static

voidmain(Stringargs[]){

newTestThread().run();//創(chuàng)建一個新線程對象,并輸出

//循環(huán)輸出

for(int

i=0;i<5;++i){System.out.println("main線程在運(yùn)行"

);

}

}}引入:單一線程的運(yùn)行流程要想運(yùn)行main()方法中的for循環(huán),必須等ThreadDemo類中的run()方法執(zhí)行完。即使該代碼塊不依賴前面的代碼塊的計算機(jī)結(jié)果,它也“無可奈何”地必須等待,這就是單一線程的缺陷。如何使兩個代碼塊能否交替輸出呢?答案是肯定的,就是Java多線程的作用了。Thread類的構(gòu)造方法

publicThread():

創(chuàng)建一個新的線程對象

publicThread(StringthreadName):創(chuàng)建一個名稱為threadName的線程對象Thread類的常用方法Interrupt():中斷線程

run():如果該線程是使用獨(dú)立的Runnable對象構(gòu)造的,則調(diào)用Runnable對象的run()方法,否則,該方法不執(zhí)行任何操作并返回。start():使該線程開始執(zhí)行,Java虛擬機(jī)調(diào)用該線程的run()方法。sleep():在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行)繼承java.lang.Thread類Thread類是Java.lang包中的一個類,Thread類的對象用來代表線程實(shí)現(xiàn)多線程的方法:通過繼承Thread類創(chuàng)建、啟動并執(zhí)行一個線程的步驟如下:創(chuàng)建一個繼承Thread類的子類覆寫Thread類的run()方法。創(chuàng)建線程類的一個對象。通過線程類的對象調(diào)用start()方法啟動線程(啟動之后會自動調(diào)用覆寫的run()方法執(zhí)行線程)繼承java.lang.Thread類繼承java.lang.Thread類public

classThreadDemoTestextendsThread{privateStringname;

publicThreadDemoTest(Stringname){

this.name=name;

}

//重寫run()方法

public

voidrun(){

for(int

i=0;i<5;i++){System.out.println(name+"運(yùn)行:"

+i);

try{

sleep((int)Math.random()*10);//正在執(zhí)行線程休眠}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}public

static

voidmain(String[]args){ThreadDemoTestt1=newThreadDemoTest("A"

);//創(chuàng)建線程對象t1ThreadDemoTestt2=newThreadDemoTest("B"

);//創(chuàng)建線程對象t2t1.start();//啟動線程t1t2.start();//啟動線程t2}}所有的線程對象都必須是Thread或者其子類的實(shí)例。創(chuàng)建一個新的線程t1,

此線程進(jìn)入新建狀態(tài);調(diào)用start()方法使得線程進(jìn)入就緒狀態(tài)使用繼承Thread類的子類來創(chuàng)建線程類時,多個線程無法共享線程類的實(shí)例變量實(shí)現(xiàn)java.lang.Runnable接口如果當(dāng)前類不僅要繼承其他類(非Thread類),還要實(shí)現(xiàn)多線程,那么如何處理呢?使用Runnable接口啟動新線程

創(chuàng)建Runnable對象;使用參數(shù)為Runnable對象的構(gòu)造方法創(chuàng)建Thread對象;調(diào)用start()方法啟動線程。Thread對象Runnable

對象啟動線程,執(zhí)行run()方法中的代碼。根據(jù)Runnable對象創(chuàng)建Thread對象調(diào)用start()方法實(shí)現(xiàn)Runnable接口創(chuàng)建線程的流程實(shí)現(xiàn)java.lang.Runnable接口classRunnableThreadDemoimplementsRunnable{

public

voidrun(){

for(int

i=0;i<5;i++){System.out.println(Thread.currentThread().getName()

+"運(yùn)行"+i);

try{

Thread.sleep(1000);//睡眠1秒}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}}public

classRunnableThread{public

static

voidmain(Stringargs[]){

RunnableThreadDemo

th=newRunnableThreadDemo();

newThread(th).start();//使用Thread類的start方法啟動線程

for(int

i=0;i<5;i++){System.out.println("main線程在運(yùn)行"

);

try{

Thread.sleep(1000);//睡眠1秒}catch(InterruptedExceptione){

e.printStackTrace();}

}

}}靜態(tài)方法currentThread(),返回值是當(dāng)前正在執(zhí)行該方法的線程實(shí)例。顯示Runnable接口相對于繼承Thread類顯著優(yōu)勢:避免了由于Java的單繼承特性帶來的局限性??墒嵌鄠€線程共享相同的資源,以達(dá)到資源共享的目的。線程生命周期及狀態(tài)線程具有生命周期,其中包含5種狀態(tài),分別為新建狀態(tài)、就緒狀態(tài)、運(yùn)行狀態(tài)、暫停狀態(tài)(包含休眠、等待和阻塞)和死亡狀態(tài)。Thread.sleep()方法Object.wait()方法Object.notify()Object.join()方法Thread.yield()案例:交通紅綠燈根據(jù)所給代碼,補(bǔ)充完整,實(shí)現(xiàn)多線程在模擬紅綠燈變化場景。多線程的同步如何解決資源共享的問題?共享資源加鎖所有解決多線程資源沖突問題的方法,都是在給定時間只允許一個線程訪問共享資源,相當(dāng)于給共享資源加道鎖。使用代碼塊實(shí)現(xiàn)線程同步使用方法實(shí)現(xiàn)線程同步多線程的同步使用代碼塊實(shí)現(xiàn)線程同步同步機(jī)制使用synchronized關(guān)鍵。每個Java對象都有一個內(nèi)置鎖,如果代碼塊使用synchronized關(guān)鍵字進(jìn)行聲明,通過鎖定指定的對象,來對同步塊中包含的代碼進(jìn)行同步,則使用該關(guān)鍵字的代碼塊稱為同步塊,也稱為臨界區(qū)。synchronized(Object)同步代碼與同步方法鎖的是對象,而不是代碼。如果某個對象被同步代碼塊或同步方法鎖住了,那么其他使用該對象的代碼必須等待,直到該對象的鎖被釋放。public

classSynchronizedTestimplementsRunnable{int

num

=10;//設(shè)置當(dāng)前總票數(shù)public

voidrun(){while(true){//設(shè)置無限循環(huán)synchronized(this){//設(shè)置同步代碼塊if(num>0){//判斷當(dāng)前票數(shù)是否大于0try{Thread.sleep(100);//使當(dāng)前線程休眠100毫秒}catch(Exceptione){e.printStackTrace();}System.out.println(Thread.currentThread().getName()+“---票數(shù)"

+num--;}}}}public

static

voidmain(String[]args){SynchronizedTestt=newSynchronizedTest();ThreadtA=newThread(t,"線程1");ThreadtB=newThread(

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論