明輝手游網(wǎng)中心:是一個免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺!

淺析Java多線程程序設(shè)計機(jī)制

[摘要]多線程是Java語言的一大特性,多線程就是同時存在N個執(zhí)行體,按幾條不同的執(zhí)行線索共同工作的情況。程序,進(jìn)程,線程,可以從不同的角度去理解。程序就是一段靜態(tài)的代碼,可以理解成一組計算機(jī)命令的集合.進(jìn)行就是這個程序一次動態(tài)的執(zhí)行過程,從代碼的加載到執(zhí)行完畢的一個過程。線程是一個比進(jìn)程小的單位,一個進(jìn)...
多線程是Java語言的一大特性,多線程就是同時存在N個執(zhí)行體,按幾條不同的執(zhí)行線索共同工作的情況。程序,進(jìn)程,線程,可以從不同的角度去理解。程序就是一段靜態(tài)的代碼,可以理解成一組計算機(jī)命令的集合.進(jìn)行就是這個程序一次動態(tài)的執(zhí)行過程,從代碼的加載到執(zhí)行完畢的一個過程。線程是一個比進(jìn)程小的單位,一個進(jìn)程再執(zhí)行的過程中可以產(chǎn)生多個線程,每個線程也是由生產(chǎn)到銷毀,可以理解成是進(jìn)行的子集。我個人用一個覺得還算恰當(dāng)?shù)谋扔鱽肀扔魅。QQ客戶端就是一個程序,登陸一個QQ就是開始了這個程序的一個進(jìn)程,再Q(mào)Q上發(fā)送消息給好友就貌似這個進(jìn)程中的一個線程。不知道這樣比喻恰當(dāng)否?

  線程也是有狀態(tài)和聲明周期的,每個Java程序都會有一個缺省的主線程,對于應(yīng)用程序applcation來說main方法就是一個主線程.Java語言使用的是Thread類及其子類的對象來表示線程的.創(chuàng)建一個新的線程的生命周期如下狀態(tài):

  1) 新建:當(dāng)一個Thread類或者其子類的對象被聲明并創(chuàng)建時,新的線程對象處于新建狀態(tài),此時它已經(jīng)有了相應(yīng)的內(nèi)存空間和其他資源.
  2) 就緒:處于新建狀態(tài)的線程被啟動后,將進(jìn)入線程隊列排隊等待CUP服務(wù),這個時候具備了運(yùn)行的條件,一旦輪到CPU的時候,就可以脫離創(chuàng)建它的主線程獨(dú)立開始自己的生命周期.
  3) 運(yùn)行:就緒的線程被調(diào)度并獲得CUP的處理邊進(jìn)入了運(yùn)行狀態(tài),每一個Thread類及其子類的對象都有一個重要的run()方法,當(dāng)線程對象被調(diào)度執(zhí)行的時候,它將自動調(diào)用本對象的run()方法,從第一句代碼開始執(zhí)行。所以說對線程的操作應(yīng)該寫到run()方法中.
  4) 阻塞:一個正在執(zhí)行的線程如果再某種情況下不能執(zhí)行了.進(jìn)入阻塞狀態(tài),這個時候它不能進(jìn)入排隊狀態(tài),只有引起了阻塞的原因消失的時候,線程才可以繼續(xù)進(jìn)入排隊狀態(tài)等待CUP處理。
  5) 死亡:處于死亡狀態(tài)的線程不具有繼續(xù)執(zhí)行的能力,線程死亡主要的原因是正常運(yùn)行的線程完成了全部工作,即執(zhí)行完了run()方法,另外就是被提前強(qiáng)制的終止了。

  線程的調(diào)度也是有優(yōu)先級別的,就是說同樣的排列優(yōu)先級高可以提前被CPU處理,主要分三個級別,高中低.分別代表的數(shù)字是10.5.1分別有三個常量代表不可以被改變。最小優(yōu)先級的常量是MIN_PRIORITY,普通的優(yōu)先級的常量是NORM_PRIORITY,最高的優(yōu)先級的常量是MAX_PRIORITY一般主線程的優(yōu)先級是普通,另外可以通過Thread類的setPriority(int a)方法來修改系統(tǒng)自動設(shè)置的線程優(yōu)先級。

  Java中編程實(shí)現(xiàn)多線程應(yīng)有兩種途徑,一種是創(chuàng)建自己的線程子類,另外是實(shí)現(xiàn)一個接口Runnable。無論是那種途徑最終讀需要使用Thread類及其方法。Thread類有兩種構(gòu)造方法,public Thread()用來創(chuàng)建一個線程對象。public Thread(Runnable r)創(chuàng)建線程對象,參數(shù)r成為被創(chuàng)建的目標(biāo)對象。這個目標(biāo)必須實(shí)現(xiàn)Runnbale接口,給出該接口的run()方法的方法體,再方法體中操作.用兩個構(gòu)造方法創(chuàng)建完的線程就是一個新建的狀態(tài),等待處理.然后啟動線程的start()方法,啟動線程對象,線程進(jìn)入排隊狀態(tài)也就是就緒狀態(tài).然后線程操作run()方法這個方法里的內(nèi)容是被系統(tǒng)處理的內(nèi)容.如果想使線程進(jìn)入休眠狀態(tài)可以調(diào)用sleep()方法,可以給一個參數(shù),代表休眠的毫秒.如果給兩個參數(shù)代表那秒。終止線程用yield()方法來完成.判斷線程是否銷毀可以用idAlive()方法判斷線程是否活著。Runnable接口只有一個方法run()方法,我們實(shí)現(xiàn)這個接口把要操作的代碼寫到這個方法中,然后再把實(shí)現(xiàn)了整個接口的類的實(shí)例傳給Therad類的構(gòu)造方法即可操作線程。

  線程同步是一個再處理線程的時候需要注意的問題,同步方法要用synchronized關(guān)鍵字類修飾,被這個關(guān)鍵字修飾后,當(dāng)一個線程A使用這個方法后,其它線程想使用這個方法就必須等待,知道線程A使用完該方法后方可使用.下面我寫一個例子來說明線程同步,這個例子有兩個線程會計和出納,他們共同有一個賬本.他們倆都可以存取方法對賬本進(jìn)行訪問,會計使用存取方法的時候?qū)懭氪驽X的記錄,出納則寫入取錢的記錄。因此會計使用賬本的時候出納被禁止使用,反之也是如此。就是一個人使用另外一個人必須等待。下面我通過一個小程序Applet來實(shí)現(xiàn)這個事:

  import Java.applet.*;
  import Java.awt.*;
  import Java.awt.event.*;

  public class MyThread extends Applet implements Runnable {
  int money = 100;
  TextArea text1 = null;
  TextArea text2 = null;
  Thread Kuaiji = null;
  Thread Chuna = null;

  public void init() {
  Kuaiji = new Thread(this);
  Chuna = new Thread(this);
  text1 = new TextArea(20,8);
  text2 = new TextArea(20,8);
  add(text1);
  add(text2);
  }

  public void start() {
  Kuaiji.start();
  Chuna.start();
  }

  public synchronized void Cunqu(int number) {
  if(Thread.currentThread() == Kuaiji) {
   for(int i=1;i <=3;i++) {="">
    money = money + number;
    try {Thread.sleep(1000);}
    catch(Exception e){}
    text1.append("\n"+money);
   }
  }
  else if(Thread.currentThread() == Chuna) {
   for(int i=1;i <=2;i++) {="">
    money = money - number/2;
    try {Thread.sleep(1000);}
    catch(Exception e){}
    text2.append("\n"+money);
   }
  }
  }

  public void run() {
  if(Thread.currentThread()==Kuaiji Thread.currentThread()==Chuna) {
   for(int i=1;i <=3;i++) {="">
    Cunqu(30);
   }
  }
  }
  }

  當(dāng)一個線程使用同步方法中的某個變量,而此變量又需要其他線程修改后才能符合本線程的需要,那么可以再同步方法中使用wait()方法,使本線程等待,并允許其他線程使用這個同步方法.用notfyAll()方法同志所有的由于使用這個同步方法的處于等待的線程結(jié)束等待進(jìn)入同步方法中運(yùn)行,如果使使用notfy()就是單獨(dú)同志一個線程進(jìn)行同步方法進(jìn)行活動.簡單的理解就是wait()方法讓線程等待,notfy()當(dāng)一個線程運(yùn)行,notfyAll()讓全部線程運(yùn)行。雖然Java支持多線程.一般線程不需要我們自己處理.但是也是需要了解和掌握的。再日后的項目中獲取會根據(jù)不同情況,有不同的需求。