隨筆-71  評(píng)論-4  文章-0  trackbacks-0
          1. 多線程
          1.1 創(chuàng)建線程類
          在Java中可以簡(jiǎn)單的從Thread類中繼承創(chuàng)建自己的線程類:

          public class MyFirstThread extends Thread {

          public void run() { . . .}

          }

          說明:

          (1) Thread類位是java.lang包中,所以可以不用顯示import;

          (2) 從Thread類中繼承下來的類最好重載run()方法,以運(yùn)行需要的代碼;

          可以按以下方法實(shí)例化并運(yùn)行線程:

          MyFirstThread aMFT = new MyFirstThread();

          aMFT.start();

          說明:

          (3) 實(shí)例化線程類后,系統(tǒng)會(huì)初始化一些參數(shù),主要是為線程創(chuàng)建名稱,把新的線程加入指定的線程組,初始化線程運(yùn)行需要的內(nèi)存空間,指定新線程的優(yōu)先級(jí)別,指定它的守候線程;

          (4) start方法是Thread類中的方法,它會(huì)調(diào)用run方法,在新的線程中運(yùn)行指定的代碼;

          (5) 除了start方法外,從Thread繼承下來的類還具有其它一些主要的方法:stop,suspend,resume等;

          以下是一個(gè)完整的Thread派生類:

          1: public class ComplexThread extends Thread {

          2: private int delay;

          3:

          4: ComplexThread(String name, float seconds) {

          5: super(name);

          6: delay = (int) seconds * 1000; // delays are in milliseconds

          7: start(); // start up ourself!

          8: }

          9:

          10: public void run() {

          11: while (true) {

          12: System.out.println(Thread.currentThread().getName());

          13: try {

          14: Thread.sleep(delay);

          15: } catch (InterruptedException e) {

          16: return;

          17: }

          18: }

          19: }

          20:

          21: public static void main(String argv[]) {

          22: new ComplexThread("one potato", 1.1F);

          23: new ComplexThread("two potato", 1.3F);

          24: new ComplexThread("three potato", 0.5F);

          25: new ComplexThread("four", 0.7F);

          26: }

          27: }

          1.2 Runable接口
          創(chuàng)建多線程運(yùn)行指定代碼的另一種方法是,在創(chuàng)建類時(shí)implement Runable這個(gè)接口:

          public class MySecondThread extends ImportantClass implements Runnable {

          public void run() {. . .}

          }

          說明:

          (1) 該類implement Runable接口,就表明有意圖運(yùn)行在單獨(dú)的線程中,Thread也是implement Runable接口的;

          (2) Implement Runalbe接口至少需要實(shí)現(xiàn)run方法;

          以下是創(chuàng)建新線程運(yùn)行該類的實(shí)例:

          MySecondThread aMST = new MySecondThread();

          Thread aThread = new Thread(aMST);

          aThread.start();

          說明:

          (3) Thread類有多個(gè)構(gòu)造函數(shù)Thread()、Thread(Runable target)等,本例中用的就是第二個(gè)構(gòu)造函數(shù),它有一個(gè)Runable類型的函數(shù),所以要在多線程中運(yùn)行的實(shí)例的類必須是implement Runable的;

          (4) AThead.start()方法調(diào)用Thread實(shí)例的中的target.run方法,本例中就是MySecondThread實(shí)例中的run方法;

          (5) Thread構(gòu)造函數(shù)還可以指定線程名,運(yùn)行所需的stack,線程所屬的組等;

          為了防止線程非正常結(jié)束,需要將start方法置入try…catch中,如:

          try{

          myThread.start();

          }catch(ThreadDeath aTD){

          System.out.println("end Thread");

          throw aTD;

          }

          在這個(gè)例子中將捕獲ThreadDeath異常,處理后重新拋出該異常,以便Java執(zhí)行stop方法,進(jìn)行資源等清理工作。

          1.3 線程的優(yōu)先級(jí)
          多個(gè)線程的執(zhí)行是有一定的優(yōu)先級(jí)別的,對(duì)于下面這個(gè)例子:

          public class RunnablePotato implements Runnable {

          public void run() {

          while (true)

          System.out.println(Thread.currentThread().getName());

          }}

          public class PotatoThreadTester {

          public static void main(String argv[]) {

          RunnablePotato aRP = new RunnablePotato();

          Thread T1 = new Thread(aRP, "one potato");

          Thread T2 = new Thread(aRP, "two potato");

          T1.start();

          T2.start();

          }}

          對(duì)于非搶占式的系統(tǒng),上例中的第一個(gè)線程會(huì)一直運(yùn)行,第二個(gè)線程沒有機(jī)會(huì)運(yùn)行;對(duì)于搶占式的系統(tǒng),這二人線程會(huì)交替運(yùn)行。

          為了讓多線程在非搶占式中運(yùn)行,最好在run方法中加入以下語(yǔ)句:

          Thread.yield()





          public void run() {

          while (true)

          System.out.println(Thread.currentThread().getName());

          Thread.yield()

          }

          Thread.yield會(huì)將當(dāng)前線程暫時(shí)讓位一小段時(shí)間,讓其它的線程有機(jī)會(huì)運(yùn)行,過了這段時(shí)間后,該線程繼承運(yùn)行。上述功能也可以用Thread.sleep()方法實(shí)現(xiàn)。

          在Java中有優(yōu)先級(jí)別可以從1到10,其中1可以用Thread.MIN_PRIORITY表示,5可以用Thread.NORM_PRIORITY,10可以用Thread.MAX_PRIORITY表示,新建一個(gè)線程默認(rèn)的級(jí)別是Thread.NORM_PRIORITY。也可以使用setPriority方法改變線程的優(yōu)先級(jí)別,如T1.setPriority(T2.getPriority + 1)。

          與yield方法相反的是join方法,它表示一直要等到指定的線程運(yùn)行完畢,如:

          try{ t.join();} catch (InterruptedException ignored) { }

          表示要等到線程t運(yùn)行完畢后,再執(zhí)行下一步操作。這種情況比較少見。

          1.4 synchronized
          為了保證某個(gè)方法或者對(duì)象某個(gè)時(shí)刻只能被一個(gè)方法訪問,那就需要使用synchronized關(guān)鍵字。

          如:

          public synchronized void countMe() {

          crucialValue += 1;

          }

          就表示countMe這個(gè)方法中的操作是一個(gè)原子操作,+= 要執(zhí)行三個(gè)步驟,使用synchronized后,這三個(gè)步驟是具有原子性,即在三個(gè)步驟完成前,其它對(duì)于crucialValue的訪問都將被拒絕,即可保證countMe的線程安全。

          另一個(gè)例子:

          synchronized(p) {

          safeX = p.x();

          safeY = p.y();

          }

          表示在block范圍內(nèi)鎖定p對(duì)象,不許其它程序修改p對(duì)象中的值。

          以上代碼的作用都是保護(hù)某個(gè)對(duì)象內(nèi)的變量不能同時(shí)被多個(gè)線程訪問,下面介紹如何保護(hù)class variable的線程安全:

          public class StaticCounter {

          private static int crucialValue;



          public void countMe() {

          synchronized(getClass()) {

          crucialValue += 1;

          } } }

          說明:

          (1) 在這個(gè)例子中,crucialValue是private并且static,這表示它可以被該類的所有實(shí)例訪問;

          (2) synchronized使用getClass方法獲取類名,而不能直接使用StaticCounter

          (3) 如果crucialValue是public的,那么修改代碼成:

          synchronized(Class.forName("StaticCounter")) {

          StaticCounter.crucialValue += 1;

          }

          posted on 2006-03-20 12:18 zjw_albert 閱讀(128) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 汉源县| 潞西市| 秦安县| 山东省| 若尔盖县| 永州市| 新民市| 自贡市| 莆田市| 左云县| 博罗县| 鹤峰县| 雷波县| 桂平市| 怀仁县| 嘉兴市| 建平县| 尉氏县| 徐闻县| 桂平市| 平湖市| 交城县| 合作市| 军事| 班戈县| 内黄县| 曲沃县| 额济纳旗| 张家川| 博客| 徐闻县| 循化| 西林县| 成安县| 资中县| 尖扎县| 平乡县| 长治市| 永新县| 大名县| 左云县|