版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第16章多線程本章要點(diǎn)了解多線程在Windows系統(tǒng)的執(zhí)行模式掌握實(shí)現(xiàn)線程的兩種方式掌握線程的狀態(tài)掌握使線程進(jìn)入各種狀態(tài)的方法掌握線程的優(yōu)先級掌握線程安全掌握線程同步機(jī)制掌握線程間的通信第16章多線程1、線程簡介2、實(shí)現(xiàn)線程的兩種方法3、線程的生命周期4、操作線程的方法5、線程的優(yōu)先級6、線程同步7、線程間的通信主要內(nèi)容16.1線程簡介世間萬物會(huì)同時(shí)完成很多工作:例如人體同時(shí)進(jìn)行呼吸、血液循環(huán)、思考問題等活動(dòng);用戶既可以使用計(jì)算機(jī)聽歌,也可以使用它打印文件,而這些活動(dòng)完全可以同時(shí)進(jìn)行,這種思想在Java中被稱為并發(fā),而將并發(fā)完成的每一件事情稱為線程。16.1線程簡介在人們的生活中,并發(fā)機(jī)制非常重要,但是并不是所有的程序語言都支持線程。在以往的程序中,多以一個(gè)任務(wù)完成后再進(jìn)行下一個(gè)項(xiàng)目的模式進(jìn)行開發(fā),這樣下一個(gè)任務(wù)的開始必須等待前一個(gè)任務(wù)的結(jié)束。Java語言提供并發(fā)機(jī)制,程序員可以在程序中執(zhí)行多個(gè)線程,每一個(gè)線程完成一個(gè)功能,并與其他線程并發(fā)執(zhí)行,這種機(jī)制被稱為多線程。16.1線程簡介Java中的多線程在每個(gè)操作系統(tǒng)中的運(yùn)行方式也存在差異,在此著重說明多線程在Windows操作系統(tǒng)的運(yùn)行模式。Windows操作系統(tǒng)是多任務(wù)操作系統(tǒng),它以進(jìn)程為單位。一個(gè)進(jìn)程是一個(gè)包含有自身地址的程序,每個(gè)獨(dú)立執(zhí)行的程序都稱為進(jìn)程,也就是正在執(zhí)行的程序。16.1線程簡介進(jìn)程是一個(gè)用來描述處于動(dòng)態(tài)運(yùn)行狀態(tài)的應(yīng)用程序的概念,即一個(gè)進(jìn)程就是一個(gè)執(zhí)行中的程序,每個(gè)進(jìn)程都有一塊自己獨(dú)立的地址空間,并可以包含多個(gè)線程。這些線程將共享進(jìn)程的地址空間及操作系統(tǒng)分配給這個(gè)進(jìn)程的資源。線程一般是指進(jìn)程中的一個(gè)執(zhí)行流,多線程是指在一個(gè)進(jìn)程中同時(shí)運(yùn)行多個(gè)不同線程,每個(gè)線程分別執(zhí)行不同的任務(wù)。16.1線程簡介系統(tǒng)可以分配給每個(gè)進(jìn)程一段有限的使用CPU的時(shí)間(也可以稱為CPU時(shí)間片),CPU在這段時(shí)間中執(zhí)行某個(gè)進(jìn)程,然后下一個(gè)時(shí)間片又跳至另一個(gè)進(jìn)程中去執(zhí)行。由于CPU轉(zhuǎn)換較快,所以使得每個(gè)進(jìn)程好像是同時(shí)執(zhí)行一樣。16.1線程簡介Windows操作系統(tǒng)的執(zhí)行模式16.1線程簡介一個(gè)線程則是進(jìn)程中的執(zhí)行流程,一個(gè)進(jìn)程中可以同時(shí)包括多個(gè)線程,每個(gè)線程也可以得到一小段程序的執(zhí)行時(shí)間,這樣一個(gè)進(jìn)程就可以具有多個(gè)并發(fā)執(zhí)行的線程。在單線程中,程序代碼按調(diào)用順序依次往下執(zhí)行,如果需要一個(gè)進(jìn)程同時(shí)完成多段代碼的操作,就需要產(chǎn)生多線程。16.2實(shí)現(xiàn)線程的兩種方式16.2.1繼承Thread類16.2.2實(shí)現(xiàn)Runnable接口16.2.1繼承Thread類Thread類是java.lang包中的一個(gè)類,從這個(gè)類中實(shí)例化的對象代表線程,程序員啟動(dòng)一個(gè)新線程需要建立Thread實(shí)例。Thread類中常用的兩個(gè)構(gòu)造方法如下:publicThread(String
threadName);publicThread();其中第一個(gè)構(gòu)造方法是創(chuàng)建一個(gè)名稱為threadName的線程對象。16.2.1繼承Thread類繼承Thread類創(chuàng)建一個(gè)新的線程的語法如下:publicclassThreadTestextendsThread{ //...}16.2.1繼承Thread類如果需要?jiǎng)?chuàng)建線程應(yīng)該先定義一個(gè)Thread類的子類,并且覆蓋其中的run()成員方法,將線程執(zhí)行的程序代碼寫在其中。Thread對象需要一個(gè)任務(wù)來執(zhí)行,任務(wù)是指線程在啟動(dòng)時(shí)執(zhí)行的工作,該工作的功能代碼被寫在run()方法中。16.2.1繼承Thread類這個(gè)run()方法必須使用如下這種語法格式:publicvoidrun(){ //...}注意:盡管在Thread的子類中覆蓋了run()成員方法,但用戶不能直接調(diào)用它,而是需要通過調(diào)用Thread類中的start()方法間接地使用它。16.2.1繼承Thread類-注意1)start()方法的調(diào)用后并不是立即執(zhí)行多線程代碼,而是使得該線程變?yōu)榭蛇\(yùn)行態(tài)(Runnable),什么時(shí)候運(yùn)行是由操作系統(tǒng)決定的。2)如果start()方法調(diào)用一個(gè)已經(jīng)啟動(dòng)的線程,系統(tǒng)將拋出IllegalThreadStateException異常。16.2.1繼承Thread類-注意main()方法線程啟動(dòng)由Java虛擬機(jī)負(fù)責(zé),程序員負(fù)責(zé)啟動(dòng)自己的線程。語法如下:publicstaticvoidmain(String[]args){ newThreadTest().start();}publicclassMyThreadextendsThread{publicvoidrun(){
for(intn=1;n<3;n++){for(inti=1;i<4;i++)
System.out.print(getName()+"("+i+")");System.out.println();}
System.out.println("exitfrom"+getName());}}創(chuàng)建兩個(gè)線程對象,分別實(shí)現(xiàn)重復(fù)顯示1~3數(shù)字的功能publicclassTest{publicstaticvoidmain(String[]args){Threadt1=newMyThread();t1.setName("T1");Threadt2=newMyThread();t2.setName("T2");t1.start();t2.start();System.out.println("exitfrom"+Thread.currentThread().getName());}}exitfrommainT2(1)T1(1)T1(2)T1(3)T2(2)T1(1)T1(2)T1(3)T2(3)exitfromT1T2(1)T2(2)T2(3)exitfromT216.2.2實(shí)現(xiàn)Runnable接口到目前為止,線程都是通過擴(kuò)展Thread類來創(chuàng)建的,如果程序員需要繼承其他類(非Thread類)并使該程序可以使用線程,就需要使用Runnable接口。實(shí)現(xiàn)Runnable接口的語法如下:publicclassMyThreadextendsObjectimplementsRunnable16.2.2實(shí)現(xiàn)Runnable接口實(shí)現(xiàn)Runnable接口的程序會(huì)創(chuàng)建一個(gè)Thread對象,并將Runnable對象與Thread對象相關(guān)聯(lián)。Thread類中有如下兩個(gè)構(gòu)造方法:publicThread(Runnabler)publicThread(Runnable
r,Stringname)這兩個(gè)構(gòu)造方法的參數(shù)中都存在Runnable實(shí)例,使用以上構(gòu)造方法就可以將Runnable實(shí)例與Thread實(shí)例相關(guān)聯(lián)。16.2.2實(shí)現(xiàn)Runnable接口使用Runnable接口啟動(dòng)新的線程的步驟如下:1)建立Runnable對象。2)使用參數(shù)為Runnable對象的構(gòu)造方法創(chuàng)建Thread實(shí)例。3)調(diào)用start()方法啟動(dòng)線程。16.2.2實(shí)現(xiàn)Runnable接口16.2.2實(shí)現(xiàn)Runnable接口通過Runnable接口創(chuàng)建線程時(shí)首先需要編寫一個(gè)實(shí)現(xiàn)Runnable接口的類,然后實(shí)例化該類的對象,這樣就建立了Runnable對象;接下來使用相應(yīng)的構(gòu)造方法創(chuàng)建Thread實(shí)例;最后使用該實(shí)例調(diào)用Thread類中的Start()方法啟動(dòng)線程。classMyThread2implements
Runnable{
privateStringname;
publicMyThread2(Stringname){
this.name=name;}public
voidrun(){
for(inti=1;i<10;i++)
System.out.println(name+"運(yùn)行:"+i);}}public
static
void
main(String[]args){
new
Thread(new
MyThread2("th1")).start();
new
Thread(new
MyThread2("th2")).start();/*MyThread2th1=newMyThread2("th1");Threadthobj1=newThread(th1);MyThread2th2=newMyThread2("th2");Threadthobj2=newThread(th2);thobj1.start();thobj2.start();*/}16.2.2實(shí)現(xiàn)Runnable接口實(shí)現(xiàn)Runnable接口比繼承Thread類所具有的優(yōu)勢:適合多個(gè)相同的程序代碼的線程去處理同一個(gè)資源可以避免java中的單繼承的限制增加程序的健壯性,代碼可以被多個(gè)線程共享,代碼和數(shù)據(jù)獨(dú)立16.3線程的生命周期線程生命周期中的各種狀態(tài)16.3線程的生命周期線程具有生命周期,其中包含7種狀態(tài),分別為出生狀態(tài)、就緒狀態(tài)、運(yùn)行狀態(tài)、等待狀態(tài)、休眠狀態(tài)、阻塞狀態(tài)和死亡狀態(tài)。出生狀態(tài)就是用戶在創(chuàng)建線程時(shí)處于的狀態(tài),在用戶使用該線程實(shí)例調(diào)用start()方法之前線程都處于出生狀態(tài);當(dāng)用戶調(diào)用start()方法后,線程處于就緒狀態(tài)(又被稱為可執(zhí)行狀態(tài));當(dāng)線程得到系統(tǒng)資源后就進(jìn)入運(yùn)行狀態(tài)。16.3線程的生命周期一旦線程進(jìn)入可執(zhí)行狀態(tài),它會(huì)在就緒與運(yùn)行狀態(tài)下輾轉(zhuǎn),同時(shí)也有可能進(jìn)入等待、休眠、阻塞或死亡狀態(tài)。當(dāng)處于運(yùn)行狀態(tài)下的線程調(diào)用Thread類中的wait()方法,該線程處于等待狀態(tài),進(jìn)入等待狀態(tài)的線程必須調(diào)用Thread類中的notify()方法才能被喚醒,而notifyAll()方法是將所有處于等待狀態(tài)下的線程喚醒;16.3線程的生命周期當(dāng)線程調(diào)用Thread類中的sleep()方法,則會(huì)進(jìn)入休眠狀態(tài)。如果一個(gè)線程在運(yùn)行狀態(tài)下發(fā)出輸入/輸出請求,該線程將進(jìn)入阻塞狀態(tài),在其等待輸入/輸出結(jié)束時(shí)線程進(jìn)入就緒狀態(tài),對于阻塞的線程來說,即使系統(tǒng)資源空閑,線程依然不能回到運(yùn)行狀態(tài);當(dāng)線程的run()方法執(zhí)行完畢時(shí),線程進(jìn)入死亡狀態(tài)。16.3線程的生命周期雖然多線程看起來像同時(shí)執(zhí)行,但事實(shí)上在同一時(shí)間點(diǎn)上只有一個(gè)線程被執(zhí)行,只是線程之間切換較快,所以才會(huì)使人產(chǎn)生線程是同時(shí)進(jìn)行的假象。在Windows操作系統(tǒng)中,系統(tǒng)會(huì)為每個(gè)線程分配一小段CPU時(shí)間片,一旦CPU時(shí)間片結(jié)束就會(huì)將當(dāng)前線程換為下一個(gè)線程,即使該線程沒有結(jié)束的情況下。16.3線程的生命周期根據(jù)圖16-5所示,可以總結(jié)出使線程進(jìn)入阻塞狀態(tài)有以下幾種可能。調(diào)用sleep()方法。調(diào)用wait()方法。等待輸入/輸出完成。16.3線程的生命周期當(dāng)線程處于阻塞狀態(tài)后,可通過以下幾種方式使線程再次進(jìn)入就緒狀態(tài)。線程調(diào)用notify()方法。線程調(diào)用notifyAll()方法。線程調(diào)用interrupt()方法。線程的休眠時(shí)間結(jié)束。
輸入/輸出結(jié)束。16.4操作線程的方法16.4.1線程的休眠16.4.2線程的加入16.4.3線程的中斷16.4.4線程的禮讓16.4.1線程的休眠一種能控制線程行為的方法是調(diào)用sleep()方法,sleep()方法需要一個(gè)參數(shù)用于指定該線程休眠的時(shí)間,該時(shí)間使用毫秒為單位。它通常是在run()方法內(nèi)的循環(huán)中被使用。sleep()方法的語法如下:try{ Thread.sleep(2000);}catch(InterruptedExceptione){
e.printStackTrace();}public
voidrun(){
System.out.println("開始執(zhí)行線程。。。");
System.out.println("進(jìn)入睡眠狀態(tài)。。。");
try{Thread.sleep(3000);}catch(InterruptedExceptione){
e.printStackTrace();}
System.out.println("線程結(jié)束。。。");}16.4.2線程的加入如果當(dāng)前某程序?yàn)槎嗑€程程序,假如存在一個(gè)線程A,現(xiàn)在需要插入線程B,并要求線程B先執(zhí)行完畢,然后再繼續(xù)執(zhí)行線程A,此時(shí)可以使用Thread類中的join()方法來完成。這就好比此時(shí)正在看電視,卻突然有人上門收水費(fèi),必須付完水費(fèi)后才能繼續(xù)看電視。當(dāng)某個(gè)線程使用join()方法加入到另外一個(gè)線程時(shí),另一個(gè)線程會(huì)等待該線程執(zhí)行完畢再繼續(xù)執(zhí)行。16.4.2線程的加入為什么要用join()方法在很多情況下,主線程生成并起動(dòng)了子線程,如果子線程里要進(jìn)行大量的耗時(shí)的運(yùn)算,主線程往往將于子線程之前結(jié)束,但是如果主線程處理完其他的事務(wù)后,需要用到子線程的處理結(jié)果,也就是主線程需要等待子線程執(zhí)行完成之后再結(jié)束,這個(gè)時(shí)候就要用到j(luò)oin()方法了。classThread1extendsThread{privateStringname;
publicThread1(Stringname){this.name=name;}
public
voidrun(){
for(inti=0;i<3;i++){
System.out.println("子線程"+name+"運(yùn)行:"+i);
try{
sleep((int)Math.random()*10);}catch(InterruptedExceptione){
e.printStackTrace();}
}
}
}public
static
void
main(String[]args){
System.out.println(Thread.currentThread().getName()+"主線程運(yùn)行開始!");
Thread1mTh1=newThread1("A");Thread1mTh2=newThread1("B");mTh1.start();mTh2.start();
System.out.println(Thread.currentThread().getName()+"主線程運(yùn)行結(jié)束!");
}main主線程運(yùn)行開始!main主線程運(yùn)行結(jié)束!子線程B運(yùn)行:0子線程A運(yùn)行:0子線程B運(yùn)行:1子線程A運(yùn)行:1子線程B運(yùn)行:2子線程A運(yùn)行:2public
static
void
main(String[]args){…
Thread1mTh1=newThread1("A");Thread1mTh2=newThread1("B");mTh1.start();mTh2.start();
try{mTh1.join();mTh2.join();}catch(InterruptedExceptione){
e.printStackTrace();}…}main主線程運(yùn)行開始!子線程B運(yùn)行:0子線程B運(yùn)行:1子線程B運(yùn)行:2子線程A運(yùn)行:0子線程A運(yùn)行:1子線程A運(yùn)行:2main主線程運(yùn)行結(jié)束!16.4.3線程的中斷以前使用stop()方法停止線程,但當(dāng)前版本的JDK早已廢除了stop()方法,同時(shí)也不建議使用stop()方法來停止一個(gè)線程的運(yùn)行?,F(xiàn)在提倡在run()方法中使用無限循環(huán)的形式,然后使用一個(gè)布爾型標(biāo)記控制循環(huán)的停止。class
ThreadTest
extendsThread{
private
intcount=10;
public
voidrun(){
while(true){
System.out.print(count+"");
if(--count==0){
return;}}}}16.4.4線程的禮讓Thread類中使用yield()方法表示禮讓,它只是給當(dāng)前正處于運(yùn)行狀態(tài)下的線程一個(gè)提醒,告知它可以將資源禮讓給其他線程。但這僅僅是一種暗示,沒有任何一種機(jī)制保證當(dāng)前線程會(huì)將資源禮讓。對于支持多任務(wù)的操作系統(tǒng)來說,不需要調(diào)用yeild()方法,因?yàn)椴僮飨到y(tǒng)會(huì)為線程自動(dòng)分配CPU時(shí)間片來執(zhí)行。16.5線程的優(yōu)先級每個(gè)線程都具有各自的優(yōu)先級,線程的優(yōu)先級可以在程序中表明該線程的重要性,如果有很多線程處于就緒狀態(tài),系統(tǒng)會(huì)根據(jù)優(yōu)先級來決定首先使哪個(gè)線程進(jìn)入運(yùn)行狀態(tài)。但這并不意味著低優(yōu)先級的線程得不到運(yùn)行,而只是它運(yùn)行的幾率比較小,比如垃圾回收線程的優(yōu)先級就較低。16.5線程的優(yōu)先級Thread類中包含的靜態(tài)成員變量代表了線程的某些優(yōu)先級,比如Thread.MIN_PRIORITY(常數(shù)1)、Thread.MAX_PRIORITY(常數(shù)10)、Thread.NORM_PRIORITY(常數(shù)5)。其中每個(gè)線程的優(yōu)先級都在Thread.MIN_PRIORITY~Thread.MAX_PRIORITY之間,在默認(rèn)情況下其優(yōu)先級都是Thread.NORM_PRIORITY。每個(gè)新產(chǎn)生的線程都繼承了父線程的優(yōu)先級。16.5線程的優(yōu)先級在多任務(wù)操作系統(tǒng)中,每個(gè)線程都會(huì)得到一小段CPU時(shí)間片運(yùn)行,在時(shí)間結(jié)束時(shí),將輪換另一個(gè)線程進(jìn)入運(yùn)行狀態(tài),這時(shí)系統(tǒng)會(huì)選擇與當(dāng)前線程優(yōu)先級相同的線程予以運(yùn)行。系統(tǒng)始終選擇就緒狀態(tài)下優(yōu)先級較高的線程進(jìn)入運(yùn)行狀態(tài)。線程的優(yōu)先級可以使用setPriority()方法調(diào)整,如果使用該方法設(shè)置的優(yōu)先級不在1~10之內(nèi),將產(chǎn)生一個(gè)IllegalArgumentException異常。16.5線程的優(yōu)先級16.5線程的優(yōu)先級在圖16-9中,優(yōu)先級為5的線程A首先得到CPU時(shí)間片;當(dāng)該時(shí)間結(jié)束后,輪換到與線程A相同優(yōu)先級的線程B;當(dāng)線程B的運(yùn)行時(shí)間結(jié)束后,會(huì)繼續(xù)輪換到線程A,直到線程A與線程B都執(zhí)行完畢,才會(huì)輪換到線程C;當(dāng)線程C結(jié)束后,最后才會(huì)輪到線程D。classMyThread51extendsThread{
publicMyThread51(Stringname){
super(name);}
public
voidrun(){
for(inti=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+"("+Thread.currentThread().getPriority()+")"+",loop"+i);}}
}
public
static
void
main(String[]args){
System.out.println(Thread.currentThread().getName()+"("+Thread.currentThread().getPriority()+")");Threadt1=newMyThread51("t1");Threadt2=newMyThread51("t2");t1.setPriority(1);t2.setPriority(10);
t1.start();t2.start();
}main(5)t1(1),loop0t1(1),loop1t1(1),loop2t1(1),loop3t1(1),loop4t2(10),loop0t2(10),loop1t2(10),loop2t2(10),loop3t2(10),loop416.6線程同步16.6.1線程安全16.6.2線程同步機(jī)制16.6.1線程安全所以在編寫多線程程序時(shí),應(yīng)該考慮到線程安全問題。實(shí)質(zhì)上線程安全問題來源于兩個(gè)線程同時(shí)存取單一對象的數(shù)據(jù)。在一個(gè)時(shí)刻只能被一個(gè)線程訪問的資源稱為臨界資源,而訪問臨界資源的那段代碼被稱為臨界區(qū)。臨界區(qū)的使用必須互斥地進(jìn)行,即一個(gè)線程在臨界區(qū)中執(zhí)行代碼時(shí),其他線程不能進(jìn)入臨界區(qū)。16.6.1線程安全在代碼中判斷當(dāng)前票數(shù)是否大于0,如果大于0則執(zhí)行將該票出售給乘客功能,但當(dāng)兩個(gè)線程同時(shí)訪問這段代碼時(shí)(假如這時(shí)只剩下一張票),第一個(gè)線程將票售出,與此同時(shí)第二個(gè)線程也已經(jīng)執(zhí)行完成判斷是否有票的操作,并得出結(jié)論票數(shù)大于0,于是它也執(zhí)行售出操作,這樣就會(huì)產(chǎn)生負(fù)數(shù)。class
ThreadSafeTest
implements
Runnable{
intnum=10;//設(shè)置當(dāng)前總票數(shù)
public
voidrun(){
while(num>0){
try{Thread.sleep(100);}catch(Exceptione){
e.printStackTrace();}
System.out.println("tickets"+num--);}}}
public
static
void
main(String[]args){
ThreadSafeTestt=new
ThreadSafeTest();ThreadtA=new
Thread(t);
//以該類對象分別實(shí)例化4個(gè)線程
ThreadtB=new
Thread(t);ThreadtC=new
Thread(t);ThreadtD=new
Thread(t);
tA.start();//分別啟動(dòng)線程
tB.start();
tC.start();
tD.start();}tickets10tickets8tickets9tickets7tickets6tickets4tickets5tickets6tickets3tickets2tickets1tickets0tickets-1tickets-216.6.2線程同步機(jī)制如何解決資源共享的問題?基本上所有解決多線程資源沖突問題都會(huì)采用給定時(shí)間只允許一個(gè)線程訪問共享資源,這時(shí)就需要給共享資源上一道鎖。為了解決多線程并發(fā)操作可能引起的數(shù)據(jù)混亂,在java中,引入對象“互斥鎖”,以保證共享數(shù)據(jù)操作的完整性。16.6.2線程同步機(jī)制1)同步塊在Java中提供了同步機(jī)制,可以有效地防止資源沖突。同步機(jī)制使用synchronized關(guān)鍵字。
synchronized(Object){}Object為任意一個(gè)對象,每個(gè)對象都存在一個(gè)標(biāo)志位,并具有兩個(gè)值,分別為0和1。一個(gè)線程運(yùn)行到同步塊時(shí)首先檢查該對象的標(biāo)志位,如果為0狀態(tài),表明此同步塊中存在其他線程在運(yùn)行。這時(shí)該線程就處于就緒狀態(tài),直到處于同步塊中的線程執(zhí)行完同步塊中的代碼為止。這時(shí)該對象的標(biāo)識位被設(shè)置為1,該線程才能執(zhí)行同步塊中的代碼,并將Object對象的標(biāo)識位設(shè)置為0,防止其他線程執(zhí)行同步塊中的代碼。
public
voidrun(){
synchronized(""){
while(num>0){
try{Thread.sleep(100);}catch(Exceptione){
e.printStackTrace();}
System.out.println("tickets"+num--);}
}}16.6.2線程同步機(jī)制2)同步方法同步方法就是在方法前面修飾synchronized關(guān)鍵字的方法,其語法如下。
synchronizedvoidf(){}當(dāng)某個(gè)對象調(diào)用了同步
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 解除醫(yī)患關(guān)系的規(guī)范流程
- 理想之城培訓(xùn)課件
- 醫(yī)患關(guān)系和諧發(fā)展策略
- 房地產(chǎn)策劃面試技巧
- 樂器行業(yè)就業(yè)前景分析
- 班級拍手節(jié)奏課件
- 京東快遞員面試內(nèi)容指南
- 精準(zhǔn)招聘話術(shù)與技巧
- 園林消防安全管理
- Chapter7Let'scelebrate語法(課件)-新版香港朗文英語六年級上冊
- 2025年12月長沙縣第二人民醫(yī)院公開招聘編外專業(yè)技術(shù)人員4人筆試考試備考試題及答案解析
- 2025年秋小學(xué)音樂湘藝版四年級上冊期末測試卷及答案
- 2025年安徽合肥廬江縣部分國有企業(yè)招聘工作人員17人筆試參考題庫附答案
- 2025九年級物理中考實(shí)驗(yàn)專項(xiàng)練習(xí)
- 小學(xué)四年級上冊口算練習(xí)題500道(A4打印版)
- 輸液連接裝置安全管理專家共識解讀
- 作詞進(jìn)階教學(xué)課件下載
- 2025上海復(fù)旦大學(xué)人事處招聘辦公室行政管理助理崗位1名考試參考試題及答案解析
- 燃?xì)庋簿€員安全培訓(xùn)課件
- 2025版離婚協(xié)議書樣本:婚姻關(guān)系解除與子女撫養(yǎng)安排
- GJB827B--2020軍事設(shè)施建設(shè)費(fèi)用定額
評論
0/150
提交評論