Java網(wǎng)絡(luò)程序設(shè)計 課件 單元8 線程應(yīng)用_第1頁
Java網(wǎng)絡(luò)程序設(shè)計 課件 單元8 線程應(yīng)用_第2頁
Java網(wǎng)絡(luò)程序設(shè)計 課件 單元8 線程應(yīng)用_第3頁
Java網(wǎng)絡(luò)程序設(shè)計 課件 單元8 線程應(yīng)用_第4頁
Java網(wǎng)絡(luò)程序設(shè)計 課件 單元8 線程應(yīng)用_第5頁
已閱讀5頁,還剩57頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

線程應(yīng)用單元八多線程創(chuàng)建和使用線程線程控制目錄CONTENTS123線程死鎖和協(xié)作目錄CONTENTS5共享數(shù)據(jù)48.1.1線程引入

在操作系統(tǒng)中,使用進程是為了使多個程序能并發(fā)執(zhí)行,以提高資源的利用率和系統(tǒng)吞吐量。在操作系統(tǒng)中再引入線程,則是為了減少采用多進程方式并發(fā)執(zhí)行時所付出的系統(tǒng)開銷,使計算機操作系統(tǒng)具有更好的并發(fā)性。

操作系統(tǒng)操作進程,付出的系統(tǒng)開銷是比較大的。所以,系統(tǒng)中的進程,其數(shù)目不宜過多,進程切換的頻率也不宜過高,這也就限制了系統(tǒng)并發(fā)性的進一步提高。

線程是進程內(nèi)一個相對獨立的、可調(diào)度的執(zhí)行單元。進程是資源分配的基本單位。與進程相對應(yīng),線程與資源分配無關(guān),它屬于某一個進程,并與進程內(nèi)的其他線程一起共享進程的資源。另外,進程擁有一個完整的虛擬地址空間,而同一進程內(nèi)的不同線程共享進程的同一地址空間。

線程是操作系統(tǒng)中的基本調(diào)度單元,進程不是調(diào)度的單元,所以每個進程在創(chuàng)建時,至少需要同時為該進程創(chuàng)建一個線程,線程也可以創(chuàng)建其他線程。進程是被分配并擁有資源的基本單元,同一進程內(nèi)的多個線程共享該進程的資源,但線程并不擁有資源,只是使用它們。由于共享資源,所以線程間需要通信和同步機制。8.1.1線程引入8.1.2線程狀態(tài)

線程是相對獨立的、可調(diào)度的執(zhí)行單元,因此在線程的運行過程中,會分別處于不同的狀態(tài)。通常而言,線程主要有下列幾種狀態(tài):(1)就緒狀態(tài):即線程已經(jīng)具備運行的條件,等待調(diào)度程序分配CPU資源給這個線程運行。(2)運行狀態(tài):調(diào)度程序分配CPU資源給該進程,該進程正在執(zhí)行。(3)阻塞狀態(tài):線程正等待某個條件符合或某個事件發(fā)生,才會具備運行的條件。下面是線程的狀態(tài)轉(zhuǎn)換圖,通過該圖,會給大家介紹線程的執(zhí)行過程和狀態(tài)轉(zhuǎn)換。

對線程的基本操作主要有以下5種,通過這五種操作,使線程在各個狀態(tài)之間轉(zhuǎn)換:派生:線程屬于進程,可以由進程派生出線程,線程所擁有的資源將會被創(chuàng)建。一個線程即可以有進程派生,也可以由線程派生。在Java中,可以創(chuàng)建一個線程并通過調(diào)用該線程的start()方法使該線程進入就緒狀態(tài)。調(diào)度:調(diào)度程序分配CPU資源給就緒狀態(tài)的線程,使線程獲得CPU資源進行運行,即執(zhí)行Java線程類中run()方法里的內(nèi)容。阻塞:正在運行狀態(tài)的線程,在執(zhí)行過程中需要等待某個條件符合或某個事件發(fā)生,此時線程進入阻塞狀態(tài)。阻塞時,寄存器上下文、程序計數(shù)器以及堆桟指針都會得到保存。激活:在阻塞狀態(tài)下的線程,如果需要等待的條件符合或事件發(fā)生,則該線程被激活并進入就緒狀態(tài)。結(jié)束:在運行狀態(tài)的線程,線程執(zhí)行結(jié)束,它的寄存器上下文以及堆棧內(nèi)容等將被釋放。8.1.2線程狀態(tài)感謝觀看,下次再見線程應(yīng)用單元八目錄CONTENTS123多線程創(chuàng)建和使用線程線程控制線程死鎖和協(xié)作目錄CONTENTS5共享數(shù)據(jù)48.2創(chuàng)建和使用線程

創(chuàng)建和使用線程,就是要讓這個線程完成一些特定的功能。在Java中,提供了java.lang.Thread類來完成多線程的編程,這個類也提供了大量的方法方便我們操作線程。我們編寫一個線程類時,可以繼承自這個Thread類,完成線程的相關(guān)工作。

如果我們編寫的線程類要繼承其他類,但Java又不支持多繼承,所以java還提供了另外一種創(chuàng)建線程的方式,即實現(xiàn)Runnable接口。8.2.1創(chuàng)建線程類

如果線程類直接繼承Thread類,其代碼結(jié)構(gòu)大致如下:。class類名extendsThread{ //屬性 //其他方法 publicvoidrun(){ //線程需要執(zhí)行的核心代碼 }}

可以看出,一個線程的核心代碼需要寫在run()方法里。也就是說,當(dāng)線程從就緒狀態(tài),通過調(diào)度程序分配CPU資源,進入運行狀態(tài)后,執(zhí)行的代碼即為run()方法里面的代碼。8.2.1創(chuàng)建線程類

如果線程類直接繼承Thread類,其代碼結(jié)構(gòu)大致如下:。class類名implementsRunnable{

//屬性

//其他方法

publicvoidrun(){

//線程需要執(zhí)行的核心代碼

}}

和繼承Thread類非常類似,實現(xiàn)Runnable接口的線程類也需要編寫run()方法,將線程的核心代碼置于該方法中。但是Runnable接口并沒有任何對線程的支持,我們還必須創(chuàng)建Thread類的實例,通過Thread類的構(gòu)造函數(shù)來創(chuàng)建線程類。類名對象名=new類名();Thread線程對象名=newThread(對象名);8.2.2多線程使用示例代碼——分別使用繼承Thread類和實現(xiàn)Runnable接口兩種方式創(chuàng)建了兩個線程類,并通過調(diào)用start()方法啟動線程:publicclassTestThread{publicstaticvoidmain(String[]args)throwsInterruptedException{Threadtl=newMyThreadl();MyThread2mt2=newMyThread2();Threadt2=newThread(mt2);t1.start();t2.start();}}//繼承自Thread類創(chuàng)建線程類classMyThreadlextendsThread{privateinti=0;//無參構(gòu)造方法,調(diào)用父類構(gòu)造方法設(shè)置線程名稱publicMyThreadl(){super("我的線程1");}//通過循環(huán)判斷,輸出10次,每次間隔0.5秒publicvoidrun(){try{while(i<10){System.out.println(this,getName()+"運行第"+(i+1)+"次");i++;//在指定的毫秒數(shù)內(nèi)讓當(dāng)前正在執(zhí)行的線程休眠(暫停執(zhí)行)sleep(500);}}catch(Exceptione){e.printStackTrace();}}}//實現(xiàn)Runnable接口創(chuàng)建線程類classMyThread2implementsRunnable{Stringname="我的線程2";publicvoidrun(){System.out.println();}}8.2.2多線程使用運行結(jié)果8.2.2多線程使用感謝觀看,下次再見線程應(yīng)用單元八目錄CONTENTS123多線程創(chuàng)建和使用線程線程控制線程死鎖和協(xié)作目錄CONTENTS5共享數(shù)據(jù)48.3.1線程控制方法

下面列舉了Thread類的一些線程控制的方法:方法名作用voidstart()使該線程開始執(zhí)行,Java虛擬機負(fù)責(zé)調(diào)用該線程的run()方法voidsleep(longmillis)靜態(tài)方法,線程進入阻塞狀態(tài),在指定時間(單位為毫秒)到達之后進入就緒狀態(tài)voidyield()靜態(tài)方法,當(dāng)前線程放棄占用CPU資源,回到就緒狀態(tài),使其他優(yōu)先級不低于此線程的線程有機會被執(zhí)行voidjoin()當(dāng)前線程等待加入的(join)線程完成,才能繼續(xù)往下執(zhí)行。voidinterrupt()中斷線程的阻塞狀態(tài)(而非中斷線程)voidisAlive()判定該線程是否就緒、運行和阻塞狀態(tài)等活動狀態(tài)。voidsetPriority(intnewPriority)設(shè)置當(dāng)前線程的優(yōu)先級。intgetPriority()獲得當(dāng)前線程的優(yōu)先級8.3.2終止線程

線程通常在三種情況下會終止,最普遍的情況是線程中的run()方法執(zhí)行完畢后線程終止,或者線程拋出了Exception或Error且未被捕獲,另外還有一種方法是調(diào)用當(dāng)前線程的stop()方法終止線程(該方法已被廢棄)。importjava.util.Scanner;publicclassEndingThread{

publicstaticvoidmain(String[]args){

CountThreadt=newCountThread();

t.start();

Scannerscanner=newScanner(System.in);

System.out.println("如果想終止輸出計數(shù)線程,請輸入s");

while(true){

Strings=scanner.nextLine();

if(s.equals("s")){

t.stopIt();

break;

}

}

}}示例代碼——通過調(diào)用線程類內(nèi)部方法實現(xiàn)終止線程的功能://計數(shù)功能線程classCountThreadextendsThread{

privateinti=0;

publicCountThread(){

super("計數(shù)線程");}8.3.2終止線程//通過設(shè)置i=l00,讓線程終止publicvoidstopIt(){

i=100;

}publicvoidrun(){

try{

while(i<100){

System.out.println(this.getName()+"計數(shù):"+(i+i));

i++;

sleep(2000);

}

}catch(Exceptione){

e.printStackTrace();

}

}}運行結(jié)果8.3.2終止線程8.3.3線程等待和中斷等待

Thread類的靜態(tài)方法sleep(),可以讓當(dāng)前線程進入等待(阻塞狀態(tài)),直到指定的時間流逝,或直到別的線程調(diào)用當(dāng)前線程對象上的interrupt()方法。示例代碼:publicclassInterruptThread{

publicstaticvoidmain(String[]args){

CountThreadt=newCountThread();

t.start();

try{

Thread.sleep(6000);}catch(InterruptedExceptione){

e.printStackTrace();

}

//中斷線程的阻塞狀態(tài)(而非中斷線程)

errupt();

}}classCountThreadextendsThread{

privateinti=0;

publicCountThread(){

super("計數(shù)線程”);}publicvoidrun(){

while(i<100){

try{

System.out.printlxi(this.getName()+"計數(shù):"+(i+1));

i++;

Thread.sleep(5000);

}catch(InterruptedExceptione){

System.out.println("程序捕獲了InterruptedException異常!");

}

System.out.println("計數(shù)線程運行1次1");

}

}}運行結(jié)果8.3.3線程等待和中斷等待

yield()方法:yield()方法和sleep()方法都是Thread類的靜態(tài)方法,都會使當(dāng)前處于運行狀態(tài)的線程放棄CPU資源,把運行機會讓給別的線程。yield()方法和sleep()方法的區(qū)別yield()方法sleep()方法yield()方法只會給相同優(yōu)先級或者更高優(yōu)先級的線程一個運行的機會。sleep()方法會給其他線程運行的機會,不考慮其他線程的優(yōu)先級,因此會給較低優(yōu)先級線程一個運行的機會。當(dāng)線程執(zhí)行了yidd()方法,將轉(zhuǎn)到就緒狀態(tài)。當(dāng)線程執(zhí)行了sleep(longmillis)方法,將轉(zhuǎn)到阻塞狀態(tài),參數(shù)millis指定了睡眠時間;yield()方法沒有聲明拋出任何異常。sleep()方法聲明拋出InterruptedException異常8.3.3線程等待和中斷等待示例代碼8.3.4等待其他線程完成

Thread類的join()方法,可以讓當(dāng)前線程等待,再加入的線程完成后,才能繼續(xù)往下執(zhí)行。publicclassJoinThread{publicstaticvoidmain(String[]args)throwsInterruptedException{SThreadst=newSThread();QThreadqt=newQThread(st);qt.start();st.start();}}classQThreadextendsThread{inti=0;Threadt=null;//構(gòu)造方法,傳入一個線程對象publicQThread(Threadt){super("QThread線程");this.t=t;}publicvoidrun(){try{while(i<100){//當(dāng)i=5,調(diào)用傳入線程對象的jion()方法,等傳入線程執(zhí)行完畢再執(zhí)行本線程if(i!=5){Thread.sleep(500);System.out.println("QThread正在每隔0.5秒輸出數(shù)字:"+i++);}else{t.join();}}}catch(InterruptedExceptione){e.printStackTrace();}}}classSThreadextendsThread{inti=0;//從0輸出到99publicvoidrun(){try{while(i<100){Thread.sleep(l000);System.out.println("SThread正在每隔1秒輸出數(shù)字:"+i++);}}catch(InterruptedExceptione){e.printStackTrace();}}}運行結(jié)果8.3.4等待其他線程完成8.3.5設(shè)置線程的優(yōu)先級

線程的優(yōu)先級由數(shù)字1~10表示,其中1表示優(yōu)先級最高,默認(rèn)值為5。盡管JDK給線程優(yōu)先級設(shè)置了10個級別,但仍然建議只使用MAX_PR10RITY(級別為1)、NORM_PRIORITY(級別為5)和MIN_PRIORITY(級別為10)三個常量來設(shè)置線程優(yōu)先級,讓程序具有更好的可移植性。publicclassSetPriority{publicstaticvoidmain(String[]args)throwsInterruptedException{QThreadqt=newQThread();SThreadst=newSThread();//給qt設(shè)置低優(yōu)先級,給st設(shè)置高優(yōu)先級qt.setPriority(Thread.MIN_PRIORITY);st.setPriority(Thread.MAX_PRIORITY);qt.start();st.start();}}示例代碼classQThreadextendsThread{inti=0;publicvoidrun(){while(i<100){System.out.println("QThread正在輸出數(shù)字:"+i++);}}}classSThreadextendsThread{inti=0;publicvoidrun(){while(i<100){System.out.println("SThread正在輸出數(shù)字:"+i++);}}}8.3.5設(shè)置線程的優(yōu)先級8.3.5設(shè)置線程的優(yōu)先級運行結(jié)果8.3.6守護線程

守護線程是為其他線程的運行提供便利的線程。Java的垃圾收集機制的某些實現(xiàn)就使用了守護線程。

程序可以包含守護線程和非守護線程,當(dāng)程序只有守護線程時,該程序便可以結(jié)束運行。

如果要使一個線程成為守護線程,則必須在調(diào)用它的start()方法之前進行設(shè)置(通過以true作為參數(shù)調(diào)用線程的setDaemon()方法,可以將該線程設(shè)置為一個守護線程)。如果線程是守護線程,則isDaemon()方法返回為true。示例代碼publicclassDaemonThread{

publicstaticvoidmain(String[]args){

DThreadt=newDThread();

t.start();

System.out.println("讓一切都結(jié)束吧");}privatestaticclassDThreadextendsThread{

//在無參構(gòu)造方法中設(shè)置本線程為守護線程

publicDThread(){

setDaemon(true);

}

publicvoidrun(){

while(true){

System.out.println("我是后臺線程");

}

}

}}8.3.6守護線程感謝觀看,下次再見線程應(yīng)用單元八目錄CONTENTS123多線程創(chuàng)建和使用線程線程控制線程死鎖和協(xié)作目錄CONTENTS5共享數(shù)據(jù)4publicclassShareData{staticintdata=0;publicstaticvoidmain(String[]args){ShareThreadlst1=newShareThread1();ShareThread2st2=newShareThread2();newThread(stl).start();newThread(st2).start();}//內(nèi)部類,訪問類中靜態(tài)成員變量dataprivatestaticclassShareThreadlimplementsRunnable{publicvoidrun(){while(data<10){try{Thread.sleep(l000);System.out.println("這個小于10的數(shù)據(jù)是:"+data++);}catch(InterruptedExceptione){e.printStackTrace();}}}}示例代碼:8.4.1數(shù)據(jù)不一致//內(nèi)部類,訪問類中靜態(tài)成員變量dataprivatestaticclassShareThread2implementsRunnable{publicvoidrun(){while(data<100){data++;}}}}

該案例說明當(dāng)一個數(shù)據(jù)被多個線程存取的時候,通過檢查這個數(shù)據(jù)的值來進行判斷并執(zhí)行之后的操作是極不安全的。因為在判斷之后,這個數(shù)據(jù)的值很可能被其他線程修改了,判斷條件也可能已經(jīng)不成立了,但此時已經(jīng)經(jīng)過了判斷,之后的操作還需要繼續(xù)進行。

8.4.2控制共享數(shù)據(jù)publicclassShareData2{staticintdata=0;//定義了一個鎖對象lockstaticfinalObjectlock=newObject();publicstaticvoidmain(String[]args){ShareThread1st1=newShareThread1();ShareThread2st2=newShareThread2();newThread(st1).start();newThread(st2).start();}示例代碼:privatestaticclassShareThread1implementsRunnable{publicvoidrun(){//對lock對象上鎖synchronized(lock){while(data<10){try{Thread.sleep(l000);System.out.println("這個小于10的數(shù)據(jù)是:"+data++);}catch(InterruptedExceptione){e.printStackTrace();}}}}}

Java提供了同步機制,來解決控制共享數(shù)據(jù)的問題,Java可以使用synchronized關(guān)鍵字確保數(shù)據(jù)在各個線程間正確共享。8.4.2控制共享數(shù)據(jù)privatestaticclassShareThread2implementsRunnable{publicvoidrun(){//對lock對象上鎖synchronized(lock){while(data<100){data++;}System.out.println("ShareThread2執(zhí)行完后data的值為:"+data);}}}}運行結(jié)果8.4.3多線程同步

多線程同步依靠的是對象鎖機制,synchronized關(guān)鍵字就是利用鎖來實現(xiàn)對共享資源的互斥訪問。實現(xiàn)多線程同步的方法之一就是同步代碼塊,其語法形式如下:

synchronized(obj){

//同步代碼塊

}要想實現(xiàn)線程的同步,則這些線程必須去競爭一個唯一的共享的對象鎖。示例代碼:publicclassTestSyncThread{publicstaticvoidmain(String[]args){for(inti=0;i<5;i++){newThread(newSyncThread(i)).start();}}}classSyncThreadimplementsjava.lang.Runnable{privateinttid;publicSyncThread(intid){this.tid=id;}publicvoidrun(){for(inti=0;i<10;i++){System.out.println("線程ID名為:"+this.tid+"正在輸出:"+i);}}}8.4.3多線程同步publicclassTestSyncThread2{publicstaticvoidmain(String[]args){//創(chuàng)建一個線程之間競爭使用的對象Objectobj=newObject();for(inti=0;i<5;i++){newThread(newSyncThread(i,obj)).start();}}}示例代碼:classSyncThreadimplementsjava.lang.Runnable{privateinttid;privateObjectlock;//構(gòu)造方法引入競爭對象publicSyncThread(intid,Objectobj){this.tid=id;this.lock=obj;}

修改TestSyncThread類,在創(chuàng)建、啟動線程之前,先創(chuàng)建一個線程之間競爭使用的對象,然后將這個對象的引用傳遞給每一個線程對象的lock成員變量。8.4.3多線程同步publicvoidrun(){synchronized(lock){for(inti=0;i<10;i++){System.out.println("線程ID名為:"+this.tid+"正在輸出:"+i);}}}}運行結(jié)果8.4.3多線程同步publicclassTestSyncThread3{publicstaticvoidmain(String[]args){for(inti=0;i<5;i++){NewThrea(newSyncThread(i).start();}}}ClassSyncThreadimplementsjava.lang.Runnable{Privateinttid;示例代碼://在線程類內(nèi)部定義一個靜態(tài)共享資源.lockprivatestaticObjectlock=newObject();publicSyncThread(intid){this.tid=id;}Publicvoidrun(){synchronized(lock){for(inti=0;i<10;i++){System.out.println("線程ID名為:"+this.tid+"正在輸出:"+i);}}}}

利用類變量被所有類的實例所共享這一特性,在線程類內(nèi)部定義一個靜態(tài)共享資源,通過對這個共享資源的競爭起到線程同步的目的。8.4.3多線程同步8.4.3多線程同步實現(xiàn)多線程同步的方法之二就是同步方法,其語法形式如下:

訪問修飾符synchronized返回類型方法名{

//同步方法體內(nèi)代碼塊

}每個類實例都對應(yīng)一把鎖,每個synchronized方法都必須獲得調(diào)用該方法的類實例的鎖方能執(zhí)行,否則所屬線程阻塞。synchronized方法一旦執(zhí)行,就獨占該鎖,直到該方法返回時才將鎖釋放,此后被阻塞的線程方能獲得該鎖,重新進入就緒狀態(tài)。這種機制確保了同一時刻對于每一個類實例,其所有聲明為synchronized的方法中至多只有一個處于就緒狀態(tài),從而有效避免了類成員變量的訪問沖突。示例代碼:publicclassTestSyncThread4{publicstaticvoidmain(String[]args){for(inti=0;i<5;i++){newThread(newSyncThread(i)).startO;}}}classSyncThreadimplementsjava.lang.Runnable{privateinttid;publicSyncThread(intid){this.tid=id;}publicvoidrun(){doTask(this.tid);}//通過類的靜態(tài)方法實現(xiàn)互斥訪問privatestaticsynchronizedvoiddoTask(inttid){for(inti=0;i<10;i++){System.out.println("線程ID名為:"+tid+"正在輸出:"+i);}}}8.4.3多線程同步感謝觀看,下次再見線程應(yīng)用單元八目錄CONTENTS123多線程創(chuàng)建和使用線程線程控制線程死鎖和協(xié)作目錄CONTENTS5共享數(shù)據(jù)48.5.1線程死鎖

多線程同步的好處是避免了線程獲取錯誤數(shù)據(jù),但多線程同步也帶來了性能問題。多線程同步采用了同步代碼塊和同步方法的方式,依靠的是鎖機制實現(xiàn)了互斥訪問。因為是互斥的訪問,所以不能并行處理,存在性能問題。

多線程同步的性能問題還只是快和慢的問題,但如果出現(xiàn)了線程死鎖,那可能直接導(dǎo)致程序眾多的線程都處于阻塞狀態(tài),無法繼續(xù)運行。publicclassDeadLockThread{//創(chuàng)建兩個線程之間競爭使用的對象privatestaticObjectlock1=newObject();privatestaticObjectlock2=newObject();publicstaticvoidmam(String[]args){newThread(newShareThreadl()).start();newThread(newShareThread2()).start();}示例代碼——線程的死鎖:privatestaticclassShareThreadlimplementsRunnable{publicvoidrun(){synchronized(lock1){try{Thread.sleep(50);}catch(InterruptedExceptione){e.printStackTrace();}synchronized(lock2){System.out.println("ShareThread1");}}}}8.5.1線程死鎖privatestaticclassShareThread2implementsRunnable{publicvoidrun(){synchronized(lock2){try{Thread.sleep(50);}catch(InterruptedExceptione){e.printStackTrace();}synchronized(lock1){System.out.println("ShareThread2");}}}}}示例代碼:8.5.1線程死鎖8.5.2線程協(xié)作

線程協(xié)作的一個典型案例就是生產(chǎn)者和消費者問題,生產(chǎn)者和消費者的這種協(xié)作是通過線程之間的握手來實現(xiàn)的,而這種握手又是通過Object類的wait()和notity()方法來實現(xiàn)。8.5.2線程協(xié)作Java提供了wait()、notify()、notifyAll()三個方法,解決線程之間協(xié)作的問題。這三個方法均是java.lang.Object類的方法,但都只能在同步方法或者同步代碼塊中使用,否則會拋出異常。voidwait()當(dāng)前線程等待,等待其他線程調(diào)用此對象的notify()方法或notifyAll()方法將其喚醒。voidnotify()喚醒在此對象鎖上等待的單個線程。voidnotifyAll()喚醒在此對象鎖上等待的所有線程。importjava.util.*;publicclassTestProdCons{//定義一個存放熱狗的集合,里面存放的是整數(shù),代表熱狗編號pri

溫馨提示

  • 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論