Java多線程程序設(shè)計入門(轉(zhuǎn))-創(chuàng)新互聯(lián)

Java

創(chuàng)新互聯(lián)是網(wǎng)站建設(shè)專家,致力于互聯(lián)網(wǎng)品牌建設(shè)與網(wǎng)絡(luò)營銷,專業(yè)領(lǐng)域包括成都做網(wǎng)站、成都網(wǎng)站設(shè)計、電商網(wǎng)站制作開發(fā)、微信平臺小程序開發(fā)、微信營銷、系統(tǒng)平臺開發(fā),與其他網(wǎng)站設(shè)計及系統(tǒng)開發(fā)公司不同,我們的整合解決方案結(jié)合了恒基網(wǎng)絡(luò)品牌建設(shè)經(jīng)驗和互聯(lián)網(wǎng)整合營銷的理念,并將策略和執(zhí)行緊密結(jié)合,且不斷評估并優(yōu)化我們的方案,為客戶提供全方位的互聯(lián)網(wǎng)品牌整合方案!多線程程序設(shè)計入門(轉(zhuǎn))[@more@]在Java語言產(chǎn)生前,傳統(tǒng)的程序設(shè)計語言的程序同一時刻只能單任務(wù)操作,效率非常低,例如程序往往在接收數(shù)據(jù)輸入時發(fā)生阻塞,只有等到程序獲得數(shù)據(jù)后才能繼續(xù)運行。隨著Internet的迅猛發(fā)展,這種狀況越來越不能讓人們?nèi)淌埽喝绻W(wǎng)絡(luò)接收數(shù)據(jù)阻塞,后臺程序就處于等待狀態(tài)而不繼續(xù)任何操作,而這種阻塞是經(jīng)常會碰到的,此時CPU資源被白白的閑置起來。如果在后臺程序中能夠同時處理多個任務(wù),該多好??!應(yīng)Internet技術(shù)而生的Java語言解決了這個問題,多線程程序是Java語言的一個很重要的特點。在一個Java程序中,我們可以同時并行運行多個相對獨立的線程,例如,我們?nèi)绻麆?chuàng)建一個線程來進行數(shù)據(jù)輸入輸出,而創(chuàng)建另一個線程在后臺進行其它的數(shù)據(jù)處理,如果輸入輸出線程在接收數(shù)據(jù)時阻塞,而處理數(shù)據(jù)的線程仍然在運行。多線程程序設(shè)計大大提高了程序執(zhí)行效率和處理能力。


  線程的創(chuàng)建


  我們知道Java是面向?qū)ο蟮某绦蛘Z言,用Java進行程序設(shè)計就是設(shè)計和使用類,Java為我們提供了線程類Thread來創(chuàng)建線程,創(chuàng)建線程與創(chuàng)建普通的類的對象的操作是一樣的,而線程就是Thread類或其子類的實例對象。下面是一個創(chuàng)建啟動一個線程的語句:


  Thread thread1=new Thread(); file://聲明一個對象實例,即創(chuàng)建一個線程;


  Thread1.run(); file://用Thread類中的run()方法啟動線程;


  從這個例子,我們可以通過Thread()構(gòu)造方法創(chuàng)建一個線程,并啟動該線程。事實上,啟動線程,也就是啟動線程的run()方法,而 Thread類中的run()方法沒有任何操作語句,所以這個線程沒有任何操作。要使線程實現(xiàn)預(yù)定功能,必須定義自己的run()方法。Java中通常有兩種方式定義run()方法:


  通過定義一個Thread類的子類,在該子類中重寫run()方法。Thread子類的實例對象就是一個線程,顯然,該線程有我們自己設(shè)計的線程體run()方法,啟動線程就啟動了子類中重寫的run()方法。


  通過Runnable接口,在該接口中定義run()方法的接口。所謂接口跟類非常類似,主要用來實現(xiàn)特殊功能,如復(fù)雜關(guān)系的多重繼承功能。在此,我們定義一個實現(xiàn)Runnable() 接口的類,在該類中定義自己的run()方法,然后以該類的實例對象為參數(shù)調(diào)用Thread類的構(gòu)造方法來創(chuàng)建一個線程。


  線程被實際創(chuàng)建后處于待命狀態(tài),激活(啟動)線程就是啟動線程的run()方法,這是通過調(diào)用線程的start()方法來實現(xiàn)的。


  下面一個例子實踐了如何通過上述兩種方法創(chuàng)建線程并啟動它們:


  // 通過Thread類的子類創(chuàng)建的線程;


   class thread1 extends Thread


    { file://自定義線程的run()方法;


     public void run()


      {


       System.out.println("Thread1 is running…");


      }


     }


   file://通過Runnable接口創(chuàng)建的另外一個線程;


  class thread2 implements Runnable


   { file://自定義線程的run()方法;


    public void run()


    {


     System.out.println("Thread2 is running…");


    }


   }


   file://程序的主類´


   class Multi_Thread file://聲明主類;


    {


     plubic static void mail(String args[]) file://聲明主方法;


      {


       thread1 threadone=new thread1(); file://用Thread類的子類創(chuàng)建線程;


       Thread threadtwo=new Thread(new thread2()); file://用Runnable接口類的對象創(chuàng)建線程;


       threadone.start(); threadtwo.start(); file://strat()方法啟動線程;


      }


     }


  運行該程序就可以看出,線程threadone和threadtwo交替占用CPU,處于并行運行狀態(tài)??梢钥闯?,啟動線程的run()方法是通過調(diào)用線程的start()方法來實現(xiàn)的(見上例中主類),調(diào)用start()方法啟動線程的run()方法不同于一般的調(diào)用方法,調(diào)用一般方法時,必須等到一般方法執(zhí)行完畢才能夠返回start()方法,而啟動線程的run()方法后,start()告訴系統(tǒng)該線程準(zhǔn)備就緒可以啟動run()方法后,就返回start()方法執(zhí)行調(diào)用start()方法語句下面的語句,這時run()方法可能還在運行,這樣,線程的啟動和運行并行進行,實現(xiàn)了多任務(wù)操作。


  線程的優(yōu)先級


  對于多線程程序,每個線程的重要程度是不盡相同,如多個線程在等待獲得CPU時間時,往往我們需要優(yōu)先級高的線程優(yōu)先搶占到CPU時間得以執(zhí)行;又如多個線程交替執(zhí)行時,優(yōu)先級決定了級別高的線程得到CPU的次數(shù)多一些且時間多長一些;這樣,高優(yōu)先級的線程處理的任務(wù)效率就高一些。


  Java中線程的優(yōu)先級從低到高以整數(shù)1~10表示,共分為10級,設(shè)置優(yōu)先級是通過調(diào)用線程對象的setPriority()方法,如上例中,設(shè)置優(yōu)先級的語句為:


  thread1 threadone=new thread1(); file://用Thread類的子類創(chuàng)建線程;
  Thread threadtwo=new Thread(new thread2()); file://用Runnable接口類的對象創(chuàng)建線程;


  threadone.setPriority(6); file://設(shè)置threadone的優(yōu)先級6;


  threadtwo.setPriority(3); file://設(shè)置threadtwo的優(yōu)先級3;


  threadone.start(); threadtwo.start(); file://strat()方法啟動線程;


  這樣,線程threadone將會優(yōu)先于線程threadtwo執(zhí)行,并將占有更多的CPU時間。該例中,優(yōu)先級設(shè)置放在線程啟動前,也可以在啟動后進行設(shè)置,以滿足不同的優(yōu)先級需求。


  線程的(同步)控制


  一個Java程序的多線程之間可以共享數(shù)據(jù)。當(dāng)線程以異步方式訪問共享數(shù)據(jù)時,有時候是不安全的或者不和邏輯的。比如,同一時刻一個線程在讀取數(shù)據(jù),另外一個線程在處理數(shù)據(jù),當(dāng)處理數(shù)據(jù)的線程沒有等到讀取數(shù)據(jù)的線程讀取完畢就去處理數(shù)據(jù),必然得到錯誤的處理結(jié)果。這和我們前面提到的讀取數(shù)據(jù)和處理數(shù)據(jù)并行多任務(wù)并不矛盾,這兒指的是處理數(shù)據(jù)的線程不能處理當(dāng)前還沒有讀取結(jié)束的數(shù)據(jù),但是可以處理其它的數(shù)據(jù)。


  如果我們采用多線程同步控制機制,等到第一個線程讀取完數(shù)據(jù),第二個線程才能處理該數(shù)據(jù),就會避免錯誤??梢姡€程同步是多線程編程的一個相當(dāng)重要的技術(shù)。


  在講線程的同步控制前我們需要交代如下概念:


  1 用Java關(guān)鍵字synchonized同步對共享數(shù)據(jù)操作的方法


  在一個對象中,用synchonized聲明的方法為同步方法。Java中有一個同步模型-監(jiān)視器,負責(zé)管理線程對對象中的同步方法的訪問,它的原理是:賦予該對象唯一一把´鑰匙´,當(dāng)多個線程進入對象,只有取得該對象鑰匙的線程才可以訪問同步方法,其它線程在該對象中等待,直到該線程用 wait()方法放棄這把鑰匙,其它等待的線程搶占該鑰匙,搶占到鑰匙的線程后才可得以執(zhí)行,而沒有取得鑰匙的線程仍被阻塞在該對象中等待。
  file://聲明同步的一種方式:將方法聲明同步


  class store


   {


    public synchonized void store_in()


    {
     ….


    }
    public synchonized void store_out(){


       ….}
    }


  2 利用wait()、notify()及notifyAll()方法發(fā)送消息實現(xiàn)線程間的相互聯(lián)系


  Java程序中多個線程通過消息來實現(xiàn)互動聯(lián)系的,這幾種方法實現(xiàn)了線程間的消息發(fā)送。例如定義一個對象的synchonized 方法,同一時刻只能夠有一個線程訪問該對象中的同步方法,其它線程被阻塞。通??梢杂胣otify()或notifyAll()方法喚醒其它一個或所有線程。而使用wait()方法來使該線程處于阻塞狀態(tài),等待其它的線程用notify()喚醒。


  一個實際的例子就是生產(chǎn)和銷售,生產(chǎn)單元將產(chǎn)品生產(chǎn)出來放在倉庫中,銷售單元則從倉庫中提走產(chǎn)品,在這個過程中,銷售單元必須在倉庫中有產(chǎn)品時才能提貨;如果倉庫中沒有產(chǎn)品,則銷售單元必須等待。


  程序中,假如我們定義一個倉庫類store,該類的實例對象就相當(dāng)于倉庫,在store類中定義兩個成員方法:store_in(),用來模擬產(chǎn)品制造者往倉庫中添加產(chǎn)品;strore_out()方法則用來模擬銷售者從倉庫中取走產(chǎn)品。然后定義兩個線程類:customer類,其中的run ()方法通過調(diào)用倉庫類中的store_out()從倉庫中取走產(chǎn)品,模擬銷售者;另外一個線程類producer中的run()方法通過調(diào)用倉庫類中的 store_in()方法向倉庫添加產(chǎn)品,模擬產(chǎn)品制造者。在主類中創(chuàng)建并啟動線程,實現(xiàn)向倉庫中添加產(chǎn)品或取走產(chǎn)品。


  如果倉庫類中的store_in() 和store_out()方法不聲明同步,這就是個一般的多線程,我們知道,一個程序中的多線程是交替執(zhí)行的,運行也是無序的,這樣,就可能存在這樣的問題:


  倉庫中沒有產(chǎn)品了,銷售者還在不斷光顧,而且還不停的在´取´產(chǎn)品,這在現(xiàn)實中是不可思義的,在程序中就表現(xiàn)為負值;如果將倉庫類中的 stroe_in()和store_out()方法聲明同步,如上例所示:就控制了同一時刻只能有一個線程訪問倉庫對象中的同步方法;即一個生產(chǎn)類線程訪問被聲明為同步的store_in()方法時,其它線程將不能夠訪問對象中的store_out()同步方法,當(dāng)然也不能訪問store_in()方法。必須等到該線程調(diào)用wait()方法放棄鑰匙,其它線程才有機會訪問同步方法。


  這個原理實際中也很好理解,當(dāng)生產(chǎn)者(producer)取得倉庫唯一的鑰匙,就向倉庫中添放產(chǎn)品,此時其它的銷售者(customer,可以是一個或多個)不可能取得鑰匙,只有當(dāng)生產(chǎn)者添放產(chǎn)品結(jié)束,交還鑰匙并且通知銷售者,不同的銷售者根據(jù)取得鑰匙的先后與否決定是否可以進入倉庫中提走產(chǎn)品。

當(dāng)前名稱:Java多線程程序設(shè)計入門(轉(zhuǎn))-創(chuàng)新互聯(lián)
文章來源:http://bm7419.com/article32/iihpc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、移動網(wǎng)站建設(shè)、做網(wǎng)站、網(wǎng)站策劃手機網(wǎng)站建設(shè)、商城網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護公司