P4-3-1 聊天信息的發(fā)送和接收_第1頁
P4-3-1 聊天信息的發(fā)送和接收_第2頁
P4-3-1 聊天信息的發(fā)送和接收_第3頁
P4-3-1 聊天信息的發(fā)送和接收_第4頁
P4-3-1 聊天信息的發(fā)送和接收_第5頁
已閱讀5頁,還剩28頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

項目四

網(wǎng)絡聊天室Java程序設計(項目式)在網(wǎng)絡聊天室中,不僅可以是兩個用戶之間通信,也可以是多個用戶聊天,此時就要通過線程來實現(xiàn)登錄用戶的聊天信息的發(fā)送和接收。任務分析12.1線程一、線程的概念1、程序、進程和線程程序是一段靜態(tài)的代碼,是應用軟件執(zhí)行的藍本。進程是程序的一次動態(tài)執(zhí)行過程,它對應了從代碼加載、執(zhí)行至執(zhí)行完畢的一個完整的過程,這個過程也是進程本身從產(chǎn)生、發(fā)展至消亡的過程。線程是比進程更小的執(zhí)行單位,一個進程在執(zhí)行過程中,可以產(chǎn)生多個線程,形成多條執(zhí)行線索,每條線索,即每個線程也有它自身的產(chǎn)生、存在和消亡的過程,也是一個動態(tài)的概念。相關知識與技術一、線程的概念1、程序、進程和線程操作系統(tǒng)使用分時管理各個進程,按時間片輪流執(zhí)行每個進程。Java的多線程就是在操作系統(tǒng)每次分時給Java程序一個時間片的CPU時間內(nèi),在若干個獨立的可控制的線程之間切換。相關知識與技術一、線程的概念1、程序、進程和線程每個Java程序都有一個默認的主線程,Java應用程序總是從主類的main方法開始執(zhí)行。當JVM加載代碼,發(fā)現(xiàn)main方法之后,就會啟動一個線程,這個線程稱作“主線程”,該線程負責執(zhí)行main方法。在main方法的執(zhí)行中再創(chuàng)建的線程,就稱為程序中的其他線程。如果main方法中沒有創(chuàng)建其他的線程,那么當main方法執(zhí)行完最后一條語句,即main方法返回時,JVM就會結束Java應用程序。如果main方法中又創(chuàng)建了其他線程,那么JVM不要在主線程和其他線程之間進行切換,保證每個線程都有機會使用CPU資源,main方法即使執(zhí)行完最后一條語句,JVM也不會結束程序,要一直等到程序的所有線程都結束之后,才結束Java應用程序。相關知識與技術二、線程的狀態(tài)與生命周期Java中使用Thread類及其子類來創(chuàng)建線程對象,每個線程都有一個誕生到消亡的生命周期,線程在生命周期中要經(jīng)歷五種狀態(tài):新建、就緒、運行、阻塞、終止。1、新建狀態(tài)當一個Thread類或其子類的對象被聲明并創(chuàng)建時,這個線程對象就處于新建狀態(tài),此時系統(tǒng)還沒有為它分配資源。

如:Threadth=newThread()相關知識與技術二、線程的狀態(tài)與生命周期2、就緒狀態(tài)也叫可執(zhí)行狀態(tài)。當一個新創(chuàng)建的線程調用start()方法后便進入了就緒狀態(tài)。處于就緒狀態(tài)的線程已經(jīng)具備了運行條件,將進入線程隊列排隊,等待系統(tǒng)為其分配CPU,一旦獲得了CPU,線程就進入了運行狀態(tài),并調用自己的run()方法。

如:th.start();相關知識與技術二、線程的狀態(tài)與生命周期3、運行狀態(tài)處于就緒狀態(tài)的線程被調度并獲得CPU的處理后便進入到運行狀態(tài)。每個Thread類及其子類的對象都有一個run()方法,當線程對象被調度執(zhí)行是,它將自動調用本對象的run()方法。要實現(xiàn)線程的功能,需要在run()方法中給出完成線程功能的操作代碼。相關知識與技術二、線程的狀態(tài)與生命周期4、阻塞狀態(tài)下面4種情況之一發(fā)生時,線程將會進入阻塞狀態(tài):調用sleep()方法使線程進入睡眠狀態(tài)。調用wait()方法使線程進入等待狀態(tài)。處于等待狀態(tài)的線程不會主動到線程隊列中排隊等待,必須由其他線程調用notify()方法通知它結束等待。線程使用CPU資源期間,執(zhí)行某個操作進入阻塞狀態(tài),如輸入輸出操作引起的阻塞。如果線程中使用synchronized(同步方法或同步代碼塊)來請求對象的鎖未獲得時,進入阻塞狀態(tài)。相關知識與技術進入阻塞狀態(tài)的線程不能進入到線程隊列排隊,只有當引起阻塞的原因消除后,如sleep設定的睡眠時間結束、其他線程使用notify方法通知結束等待、輸入輸出操作完成等,線程才能重新進入到線程隊列中排隊等待CPU資源,以便從中斷處繼續(xù)運行。相關知識與技術二、線程的狀態(tài)與生命周期5、終止狀態(tài)處于終止狀態(tài)的線程不再具有繼續(xù)運行的能力。線程終止的原因有兩個:線程完成了它的全部工作,即執(zhí)行完run()方法中的全部語句,結束了run()方法的執(zhí)行,線程正常終止。線程被提前強制性地終止,即強制結束run()方法的執(zhí)行。相關知識與技術三、線程調度與優(yōu)先級處于就緒狀態(tài)的線程首先進入就緒隊列排隊等候CPU資源,同一時刻在就緒隊列中的線程可能有多個。JVM中的線程調度器負責管理線程,調度器把線程的優(yōu)先級分為10個級別,分別用Thread類中的類常量表示。每個Java線程的優(yōu)先級都在常數(shù)1-10之間,即Thread.MIN_PRIORITY(1)和Thread.MAX_PRIORITY(10),如果沒有明確地設置線程的優(yōu)先級別,每個線程的優(yōu)先級都為常數(shù)5,即Thread.NORM_PRIORITY(5)。線程的優(yōu)先級可以通過setPriority(intgrade)方法調整,如果參數(shù)不在1-10之間,則會產(chǎn)生一個IllegalArgumenException異常。getPriority方法返回線程的優(yōu)先級。相關知識與技術三、線程調度與優(yōu)先級在采用時間片的系統(tǒng)中,每個線程都有機會獲得CPU的使用權,以便使用CPU資源執(zhí)行線程中的操作。當線程使用CPU資源的時間到了,即使線程沒有完成自己的全部操作,Java調度器也會中斷當前線程的執(zhí)行,把CPU的使用權切換給下一個排隊等待的線程,當前線程將等待CPU資源的下一次輪回,然后從中斷處繼續(xù)執(zhí)行。Java調度器的任務是使高優(yōu)先級的線程能始終運行,一旦時間片有空閑,剛使具有同等優(yōu)先級的線程以輪流的方式順序使用時間片。也就是說,如果有A、B、C、D4個線程,A和B的級別高于C和D,那么,Java調度器首先以輪流的方式執(zhí)行A和B,一直等到A、B都執(zhí)行完畢進入死亡狀態(tài),才會在C、D之間輪流切換。相關知識與技術12.2線程的實現(xiàn)Java中創(chuàng)建線程有兩種方法:通過繼承Thread類來創(chuàng)建線程,在子類中重寫run方法。通過實現(xiàn)Runnable接口來創(chuàng)建線程,創(chuàng)建類使用Runnable接口及并實現(xiàn)run方法。相關知識與技術一、Thread類java.lang包中的Thread類,是一個專門用來創(chuàng)建線程的類,該類中提供了線程所用到的屬性和方法。Thread類的構造方法publicThread():publicThread(Stringname)publicThread(Runnabletarget)publicThread(Runnable

target,Stringname)publicThread(ThreadGroup

group,Stringname)publicThread(ThreadGroup

group,Runnabletarget)publicThread(ThreadGroup

group,Runnable

target,Stringname)相關知識與技術二、通過繼承Thread類實現(xiàn)線程通過繼承Thread類實現(xiàn)線程的步驟是:(1)定義一個線程類,它繼承線程類Thread并重寫其中的run()方法。(2)創(chuàng)建該子類的對象,即創(chuàng)建線程對象。(3)線程對象調用start方法啟動線程,將執(zhí)行權轉交給run()方法。相關知識與技術三、通過實現(xiàn)Runnable接口實現(xiàn)線程通過實現(xiàn)Runnable接口實現(xiàn)線程的步驟是:(1)定義一個類實現(xiàn)Runnable接口,即在該類中提供run()方法的實現(xiàn)。(2)把Runnable的一個實例作為參數(shù)傳遞給Thread類的一個構造方法。(3)線程對象調用start方法啟動線程,將執(zhí)行權轉交給run()方法。相關知識與技術12.3線程的常用方法1、start()方法線程調用該方法將啟動線程,使之從新建狀態(tài)進入就緒隊列排隊,一旦輪到它來享用CUP資源,就可以脫離創(chuàng)建它的線程獨立開始自己的生命周期了。2、run()方法Thread類的run()方法與Runnable接口中的run()方法的功能和作用相同,都是用來定義線程對象被調度之后所執(zhí)行的操作,都是系統(tǒng)自動調用而用戶程序不得引用的方法。當run()方法執(zhí)行完畢,線程就變成死亡狀態(tài),所謂死亡狀態(tài)就是線程釋放了實體,即釋放分配給線程對象的內(nèi)存。在線程沒有結束run()方法之前,不贊成讓線程再調用start()方法,否則將產(chǎn)生IllegalThreadStateException異常相關知識與技術3、sleep(int

millsecond)方法線程的調度執(zhí)行是按照其優(yōu)先級的高低順序進行的,當優(yōu)先級高的線程未死亡時,優(yōu)先級低的線程沒有機會獲得CPU資源。有時,優(yōu)先級高的線程需要優(yōu)先低的線程做一些工作來配合它,或者優(yōu)先級高的線程需要完成一些費時的操作,此時優(yōu)先級高的線程應該讓出CPU資源,使優(yōu)先級低的線程有機會執(zhí)行。為達到這個目的,優(yōu)先級高的線程可以在它的run()方法中調用sleep方法來使自己放棄CPU資源,休眠一段時間。休眠時間的長短由sleep方法的參數(shù)決定。如果線程在休眠時被打斷,JVM就拋出InterruptedException異常,因此,必須在try-catch語句塊中調用sleep方法。相關知識與技術4、isAlive方法線程處于“新建”狀態(tài)時,線程調用isAlive()方法返回false。當一個線程調用start()方法,并占用CPU資源后,該線程的run()方法結束之前,即沒有進入死亡狀態(tài)之前,線程調用isAlive()方法返回true。當線程進入“死亡”狀態(tài)后(實體內(nèi)存被釋放),線程仍可以調用isAlive()方法,這時返回的值是false。

注意:一個已經(jīng)運行的線程沒有進入死亡狀態(tài)是,不要再給線程分配實體,由于線程只能引用最后分配的實體,先前的實體就會成為“垃圾”,并且不會被垃圾收集機制收集掉。相關知識與技術5、currentThread()方法該方法是Thread類的類方法,可以用類名調用,該方法返回當前正在使用CPU資源的線程。6、interrupt()方法該方法經(jīng)常用來“吵醒”休眠的線程。當一些線程調用sleep方法處于休眠狀態(tài)時,一個占有CPU資源的線程可以讓休眠的線程調用interrupt方法“吵醒”自己,即導致休眠的線程發(fā)生InterruptedException異常,從而結束休眠,重新排隊等待CPU資源。相關知識與技術12.4線程的同步一、線程同步在多線程的程序中,要求各個線程對共享資源的訪問是互斥的。比如鐵路售票系統(tǒng),有4個售票點發(fā)售某日某次列車的100張車票,票是共享資源,其中一個售票點在發(fā)售某張票的時候,其余售票點便不能進行售票,必須等這個售票點發(fā)售完這一張票,釋放對共享資源的使用權后,才能進行售票。如代碼:

if(tickets)tickets--;

當一個售票線程運行到if后,必須等到if語句執(zhí)行完畢后,才能將控制權交給其他線程,即不可能有多個線程同時在這兩句代碼之間執(zhí)行,這就是線程同步。相關知識與技術一、線程同步在處理線程同步時,要做的第一件事就是要把修改數(shù)據(jù)的方法或代碼段用關鍵字synchronized來修飾,一個方法或代碼段使用關鍵字synchronized修飾后,當一個線程A使用這個方法時,其他線程想使用這個方法時就必須等待,直到線程A使用完該方法。所謂線程同步就是若干個線程都需要使用一個synchronized修飾的方法。相關知識與技術二、wait()、notify()、notifyAll方法對于同步方法,有時涉及某些特殊情況,比如當一個人在售票窗口排隊購買電影票時,如果給售票員的錢不是零錢,而售票員又沒有零錢找時,那么他必須等待,并允許后面的人買票,以便售票員獲得零錢后找零。如果第二個人仍沒有零錢,那么兩人必須等待,并允許后面的人買票。即當一個線程使用的同步方法中用到某個變量,而此變量又需要其他線程修改后才能符合本線程的需要,那么可以在同步方法中使用wait()方法。相關知識與技術二、wait()、notify()、notifyAll方法wait()方法可以中斷方法的執(zhí)行,使本線程等待,暫時讓出CPU的使用權,并允許其他線程使用這個同步方法。notifyAll():其他線程如果在使用這個同步方法時不需要等待,那么它使用完這個同步方法的同時,應當用notify()方法通知所有的由于使用這個同步方法而處于等待的線程結束等待,曾中斷的線程就會從剛才的中斷處繼續(xù)執(zhí)行這個同步方法,并遵循“先中斷先繼續(xù)”的原則。Notify():通知處于等待中的線程的某一個結束等待。相關知識與技術二、wait()、notify()、notifyAll方法案例11-4-2:模擬兩個人,張某和李某買電影票,售票員只有兩張5元的錢,電影票5元錢一張,張某拿20元一張的人民幣排在李某的前面買票,李某拿一張5元的人民幣買票,因此,張某必須等待。相關知識與技術12.5線程聯(lián)合一個線程A在占用CPU資源期間,可以讓其他線程調用join()和本線程聯(lián)合,如

B.join()

稱線程A在運行期間聯(lián)合了線程B。如果線程A在占有CPU資源期間一旦聯(lián)合線程B,那么線程A將立刻中斷執(zhí)行,一直等到它聯(lián)合的線程B執(zhí)行完畢,線程A再重新排隊等待CPU資源,以便恢復執(zhí)行。如果線程A準備聯(lián)合的線程B已經(jīng)結束,那么B.join()不會產(chǎn)生任何效果。相關知識與技術服務器端主要代碼://用于接收每一個具體客戶消息的線程類privateclassServerThreadSingleextendsThread{//創(chuàng)建Socket對象,實現(xiàn)網(wǎng)絡通信,通過服務器名稱和端口號publicSocketsocket;privateDataInputStreamin;//網(wǎng)絡數(shù)據(jù)接收流privateDataOutputStreamout;//網(wǎng)絡數(shù)據(jù)發(fā)送流privatebooleanlogin;//用戶登錄狀態(tài)privateStringuserName;//當前用戶名稱任務實施publicServerThreadSingle(Socket_socket){try{socket=_socket;in=newDataInputStream(socket.getInputStream());//網(wǎng)絡數(shù)據(jù)接收流out=newDataOutputStream(socket.getOutputStream());//網(wǎng)絡數(shù)據(jù)發(fā)送流login=false;//初始化處于未登錄狀態(tài)userName=ne

溫馨提示

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

最新文檔

評論

0/150

提交評論