隨筆-42  評(píng)論-42  文章-0  trackbacks-0
          用于線程實(shí)現(xiàn)的類和接口分別是什么?簡(jiǎn)單舉出使用范例。

          JAVA線程的實(shí)現(xiàn)--Thread類與Runnable接口

            要記住的一件重要的事情是main() 函數(shù)也是一個(gè)線程,并可用來(lái)做有用的工作。程序員只有在需要多個(gè)線程時(shí)才需要?jiǎng)?chuàng)建新的線程。
            Thread 類
            Thread 類是一個(gè)具體的類,而非抽象類.該類封裝了線程的行為。要?jiǎng)?chuàng)建一個(gè)線程,必須創(chuàng)建一個(gè)從 Thread 類繼承的新類。程序員必須覆蓋 Thread 的 run() 函數(shù)來(lái)完成有用的工作。用戶并不直接調(diào)用此函數(shù);而是必須調(diào)用 Thread 的 start() 函數(shù),該函數(shù)再調(diào)用 run()。下面的代碼說(shuō)明了它的用法:
            創(chuàng)建兩個(gè)新線程:

          import java.util.*;

          class TimePrinter extends Thread {
           
          int pauseTime;
           String name;
           
          public TimePrinter(int x, String n) {
            pauseTime 
          = x;
            name 
          = n;
           }


           
          public void run() {
            
          while(true{
             
          try {
              System.out.println(name 
          + ":" + new    
                     Date());
              Thread.sleep(pauseTime);
             }
           catch(Exception e) {
              System.out.println(e);
             }

            }

           }


           
          static public void main(String args[]) {
            TimePrinter tp1 
          = new TimePrinter(1000"Fast Guy");
            tp1.start();
            TimePrinter tp2 
          = new TimePrinter(3000"Slow Guy");
            tp2.start();

           }

          }
           在本例中,我們可以看到一個(gè)簡(jiǎn)單的程序,它按兩個(gè)不同的時(shí)間間隔(1 秒和 3 秒)在屏幕上顯示當(dāng)前時(shí)間。這是通過(guò)創(chuàng)建兩個(gè)新線程來(lái)完成的,包括 main() 共三個(gè)線程。但是,因?yàn)橛袝r(shí)要作為線程運(yùn)行的類可能已經(jīng)是某個(gè)類層次的一部分,所以就不能再按這種機(jī)制創(chuàng)建線程。雖然在同一個(gè)類中可以實(shí)現(xiàn)任意數(shù)量的接口,但 Java 編程語(yǔ)言只允許一個(gè)類有一個(gè)父類。同時(shí),某些程序員避免從 Thread 類導(dǎo)出,因?yàn)樗鼜?qiáng)加了類層次。對(duì)于這種情況,就要 runnable 接口。

            Runnable 接口
            此接口只有一個(gè)函數(shù),run(),此函數(shù)必須由實(shí)現(xiàn)了此接口的類實(shí)現(xiàn)。但是,就運(yùn)行這個(gè)類而論,其語(yǔ)義與前一個(gè)示例稍有不同。我們可以用 runnable 接口改寫(xiě)前一個(gè)示例。
            創(chuàng)建兩個(gè)新線程而不強(qiáng)加類層次:
          import java.util.*;

          class TimePrinter implements Runnable {
           
          int pauseTime;
           String name;
           
          public TimePrinter(int x, String n) {
            pauseTime 
          = x;
            name 
          = n;
           }


           
          public void run() {
            
          while(true{
             
          try {
              System.out.println(name 
          + ":" + new Date());
              Thread.sleep(pauseTime);
             }
           catch(Exception e) {
              System.out.println(e);
             }

            }

           }


           
          static public void main(String args[]) {
            Thread t1 
          = new Thread(new TimePrinter(1000"Fast Guy"));
            t1.start();
            Thread t2 
          = new Thread(new TimePrinter(3000"Slow Guy"));
            t2.start();
           }

          }
           請(qǐng)注意,當(dāng)使用 runnable 接口時(shí),不能直接創(chuàng)建所需類的對(duì)象并運(yùn)行它;必須從 Thread 類的一個(gè)實(shí)例內(nèi)部運(yùn)行它。許多程序員更喜歡 runnable 接口,因?yàn)閺?Thread 類繼承會(huì)強(qiáng)加類層次。

          練習(xí):
          package thread;

          import java.util.Date;

          public class ThreadTest2 extends Thread {
              
          private String name;
              
          private int time;

              
          public ThreadTest2(String name, int time) {
                  
          super();
                  
          this.name = name;
                  
          this.time = time;
              }


              @Override
              
          public void run() {
                  
          try {
                      Thread.sleep(time);
                      System.out.println(name 
          + ":" + new Date());
                  }
           catch (Exception e) {
                      
          // TODO: handle exception
                  }

              }


              
          public static void main(String[] args) {
                  System.out.println(
          "chh");
                  ThreadTest2 tt2 
          = new ThreadTest2("yiqi"5000);
                  tt2.start();
              }

          }



          package thread;

          import java.util.Date;

          public class RunnableImpl2 implements Runnable {

              
          private long time;

              
          public RunnableImpl2(long time) {
                  
          super();
                  
          this.time = time;
              }


              @Override
              
          public void run() {
                  
          try {
                      Thread.sleep(time);
                      System.out.println(
          "jn" + ":" + new Date());
                  }
           catch (Exception e) {
                      
          // TODO: handle exception
                  }

              }


              
          public static void main(String[] args) {
                  Thread td 
          = new Thread(new RunnableImpl2(5000));
                  td.start();
                  System.out.println(
          "haha" + ":" + new Date());

              }

          }



            synchronized(同步的) 關(guān)鍵字
           
            到目前為止,我們看到的示例都只是以非常簡(jiǎn)單的方式來(lái)利用線程。只有最小的數(shù)據(jù)流,而且不會(huì)出現(xiàn)兩個(gè)線程訪問(wèn)同一個(gè)對(duì)象的情況。但是,在大多數(shù)有用的程序中,線程之間通常有信息流。試考慮一個(gè)金融應(yīng)用程序,它有一個(gè) Account 對(duì)象,如下例中所示:
            一個(gè)銀行中的多項(xiàng)活動(dòng):

           
          public class Account {
           String holderName;
           
          float amount;
           
          public Account(String name, float amt) {
           holderName 
          = name;
           amount 
          = amt;
          }


          public void deposit(float amt) {
           amount 
          += amt;
          }


          public void withdraw(float amt) {
           amount 
          -= amt;
          }


          public float checkBalance() {
           
          return amount;
          }

          }

           在此代碼樣例中潛伏著一個(gè)錯(cuò)誤。如果此類用于單線程應(yīng)用程序,不會(huì)有任何問(wèn)題。但是,在多線程應(yīng)用程序的情況中,不同的線程就有可能同時(shí)訪問(wèn)同一個(gè) Account 對(duì)象,比如說(shuō)一個(gè)聯(lián)合帳戶的所有者在不同的 ATM 上同時(shí)進(jìn)行訪問(wèn)。在這種情況下,存入和支出就可能以這樣的方式發(fā)生:一個(gè)事務(wù)被另一個(gè)事務(wù)覆蓋。這種情況將是災(zāi)難性的。但是,Java 編程語(yǔ)言提供了一種簡(jiǎn)單的機(jī)制來(lái)防止發(fā)生這種覆蓋。每個(gè)對(duì)象在運(yùn)行時(shí)都有一個(gè)關(guān)聯(lián)的鎖。這個(gè)鎖可通過(guò)為方法添加關(guān)鍵字 synchronized 來(lái)獲得。這樣,修訂過(guò)的 Account 對(duì)象(如下所示)將不會(huì)遭受像數(shù)據(jù)損壞這樣的錯(cuò)誤:
          public class Account {
           String holderName;
           
          float amount;
           
          public Account(String name, float amt) {
           holderName 
          = name;
           amount 
          = amt;
          }


          public synchronized void deposit(float amt) {
           amount 
          += amt;
          }


          public synchronized void withdraw(float amt) {
           amount 
          -= amt;
          }


          public float checkBalance() {
           
          return amount;
          }

          }

            對(duì)一個(gè)銀行中的多項(xiàng)活動(dòng)進(jìn)行同步處理:

            deposit() 和 withdraw() 函數(shù)都需要這個(gè)鎖來(lái)進(jìn)行操作,所以當(dāng)一個(gè)函數(shù)運(yùn)行時(shí),另一個(gè)函數(shù)就被阻塞。請(qǐng)注意, checkBalance() 未作更改,它嚴(yán)格是一個(gè)讀函數(shù)。因?yàn)?checkBalance() 未作同步處理,所以任何其他方法都不會(huì)阻塞它,它也不會(huì)阻塞任何其他方法,不管那些方法是否進(jìn)行了同步處理.



          關(guān)于synchronized

          1、synchronized關(guān)鍵字的作用域有二種:

          1)是某個(gè)對(duì)象實(shí)例內(nèi),synchronized aMethod(){}可以防止多個(gè)線程同時(shí)訪問(wèn)這個(gè)對(duì)象的synchronized方法(如果一個(gè)對(duì)象有多個(gè)synchronized方法,只要一個(gè)線程訪問(wèn)了其中的一個(gè)synchronized方法,其它線程不能同時(shí)訪問(wèn)這個(gè)對(duì)象中任何一個(gè)synchronized方法)。這時(shí),不同的對(duì)象實(shí)例的synchronized方法是不相干擾的。也就是說(shuō),其它線程照樣可以同時(shí)訪問(wèn)相同類的另一個(gè)對(duì)象實(shí)例中的synchronized方法;

          2)是某個(gè)類的范圍,synchronized static aStaticMethod{}防止多個(gè)線程同時(shí)訪問(wèn)這個(gè)類中的synchronized static 方法。它可以對(duì)類的所有對(duì)象實(shí)例起作用。

          2、除了方法前用synchronized關(guān)鍵字,synchronized關(guān)鍵字還可以用于方法中的某個(gè)區(qū)塊中,表示只對(duì)這個(gè)區(qū)塊的資源實(shí)行互斥訪問(wèn)。用法是: synchronized(this){/*區(qū)塊*/},它的作用域是當(dāng)前對(duì)象;

          3、synchronized關(guān)鍵字是不能繼承的,也就是說(shuō),基類的方法synchronized f(){} 在繼承類中并不自動(dòng)是synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個(gè)方法為synchronized方法;



          posted on 2008-06-17 20:55 BlueSunshine 閱讀(295) 評(píng)論(7)  編輯  收藏 所屬分類: 參考資料

          評(píng)論:
          # re: 面試題 2008-06-18 12:23 | BlueSunshine
          collection 與 collections 的區(qū)別

           Collection是集合的接口(不包括 map), set 和 list 這兩個(gè)接口繼承了 collection 接口;
          Collections是針對(duì)集合類的一個(gè)幫助類,他提供一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作。
            回復(fù)  更多評(píng)論
            
          # re: 面試題 2008-06-18 12:26 | BlueSunshine
          final, finally, finalize的區(qū)別

          final 用于聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。
          finally是異常處理語(yǔ)句結(jié)構(gòu)(可選的)的一部分,表示總是執(zhí)行。try{}catch(){}finally{}
          finalize是Object類的一個(gè)方法,在垃圾收集器執(zhí)行的時(shí)候會(huì)調(diào)用被回收對(duì)象的此方法,可以覆蓋此方法提供垃圾收集時(shí)的其他資源回收,例如關(guān)閉文件等。
            回復(fù)  更多評(píng)論
            
          # re: 面試題 2008-06-18 12:41 | BlueSunshine
          HashMap和Hashtable的區(qū)別
           
            Hashtable繼承自Dictionary類(Dictionary類也實(shí)現(xiàn)了Map 接口),而HashMap是Java1.2引進(jìn)的Map interface的一個(gè)實(shí)現(xiàn)類。他們都實(shí)現(xiàn)了Map接口。Hashtable和HashMap采用的hash/rehash算法都大概一樣,所以性能不會(huì)有很大的差異。

            區(qū)別1:HashMap允許將null作為一個(gè)entry(名值對(duì))的key或者value,由于非線程安全,效率上可能高于Hashtable,而Hashtable不允許。HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因?yàn)閏ontains方法容易讓人引起誤解。

            區(qū)別2:Hashtable的方法是Synchronize的,而HashMap不是,在多個(gè)線程訪問(wèn)Hashtable時(shí),不需要自己為它的方法實(shí)現(xiàn)同步,而HashMap 就必須為之提供外同步。
            回復(fù)  更多評(píng)論
            
          # re: 面試題 2008-06-18 12:51 | BlueSunshine
          session 與cookie 的區(qū)別
           
            Session是由應(yīng)用服務(wù)器維持的一個(gè)服務(wù)器端的存儲(chǔ)空間,Cookie是客戶端的存儲(chǔ)空間,由瀏覽器來(lái)維持。用戶在連接服務(wù)器時(shí),會(huì)由服務(wù)器生成一個(gè)唯一的SessionID,用該SessionID 為標(biāo)識(shí)符來(lái)存取服務(wù)器端的Session存儲(chǔ)空間。而SessionID這一數(shù)據(jù)則是保存到客戶端,用Cookie保存的,用戶提交頁(yè)面時(shí),會(huì)將這一 SessionID提交到服務(wù)器端,來(lái)存取Session數(shù)據(jù)。
           
            
            服務(wù)器也可以通過(guò)URL重寫(xiě)的方式來(lái)傳遞SessionID的值,因此不是完全依賴Cookie。如果客戶端Cookie禁用,則服務(wù)器可以自動(dòng)通過(guò)重寫(xiě)URL的方式來(lái)保存Session的值,并且這個(gè)過(guò)程對(duì)程序員透明。可以試一下,即使不寫(xiě)Cookie,在使用request.getCookies();取出的Cookie數(shù)組的長(zhǎng)度也是1,而這個(gè)Cookie的名字就是JSESSIONID,還有一個(gè)很長(zhǎng)的二進(jìn)制的字符串,是SessionID的值。

            回復(fù)  更多評(píng)論
            
          # re: 面試題 2008-06-18 13:06 | BlueSunshine
          JVM
           
          Java Virtual Machine(Java虛擬機(jī)),它是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),是通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的。Java虛擬機(jī)有自己完善的硬件架構(gòu),如處理器、堆棧、寄存器等,還具有相應(yīng)的指令系統(tǒng)。JVM屏蔽了與具體操作系統(tǒng)平臺(tái)相關(guān)的信息,使得Java程序只需生成在Java虛擬機(jī)上運(yùn)行的目標(biāo)代碼(字節(jié)碼),就可以在多種平臺(tái)上不加修改地運(yùn)行。Java虛擬機(jī)在執(zhí)行字節(jié)碼時(shí),實(shí)際上最終還是把字節(jié)碼解釋成具體平臺(tái)上的機(jī)器指令執(zhí)行。
            回復(fù)  更多評(píng)論
            
          # re: 面試題 2008-06-18 13:16 | BlueSunshine
          Servlet
           
            Servlet是使用Java Servlet 應(yīng)用程序設(shè)計(jì)接口(API)及相關(guān)類和方法的 Java 程序。除了 Java Servlet API,Servlet 還可以使用用以擴(kuò)展和添加到 API 的 Java 類軟件包。Servlet 在啟用 Java 的 Web 服務(wù)器上或應(yīng)用服務(wù)器上運(yùn)行并擴(kuò)展了該服務(wù)器的能力。Java servlet對(duì)于Web服務(wù)器就好象Java applet對(duì)于Web瀏覽器。Servlet裝入Web服務(wù)器并在Web服務(wù)器內(nèi)執(zhí)行,而applet裝入Web瀏覽器并在Web瀏覽器內(nèi)執(zhí)行。Java Servlet API 定義了一個(gè)servlet 和Java使能的服務(wù)器之間的一個(gè)標(biāo)準(zhǔn)接口,這使得Servlets具有跨服務(wù)器平臺(tái)的特性。
            Servlet 通過(guò)創(chuàng)建一個(gè)框架來(lái)擴(kuò)展服務(wù)器的能力,以提供在 Web 上進(jìn)行請(qǐng)求和響應(yīng)服務(wù)。當(dāng)客戶機(jī)發(fā)送請(qǐng)求至服務(wù)器時(shí),服務(wù)器可以將請(qǐng)求信息發(fā)送給 Servlet,并讓 Servlet 建立起服務(wù)器返回給客戶機(jī)的響應(yīng)。 當(dāng)啟動(dòng) Web 服務(wù)器或客戶機(jī)第一次請(qǐng)求服務(wù)時(shí),可以自動(dòng)裝入 Servlet。裝入后, Servlet 繼續(xù)運(yùn)行直到其它客戶機(jī)發(fā)出請(qǐng)求。Servlet 的功能涉及范圍很廣。例如,Servlet 可完成如下功能:

           

          (1) 創(chuàng)建并返回一個(gè)包含基于客戶請(qǐng)求性質(zhì)的動(dòng)態(tài)內(nèi)容的完整的 HTML頁(yè)面。

          (2) 創(chuàng)建可嵌入到現(xiàn)有 HTML 頁(yè)面中的一部分 HTML 頁(yè)面(HTML 片段)。

          (3) 與其它服務(wù)器資源(包括數(shù)據(jù)庫(kù)和基于 Java 的應(yīng)用程序)進(jìn)行通信。

          (4) 用多個(gè)客戶機(jī)處理連接,接收多個(gè)客戶機(jī)的輸入,并將結(jié)果廣播到多個(gè)客戶機(jī)上。例如,Servlet 可
          以是多參與者的游戲服務(wù)器。

          (5) 當(dāng)允許在單連接方式下傳送數(shù)據(jù)的情況下,在瀏覽器上打開(kāi)服務(wù)器至applet的新連接,并將該連
          接保持在打開(kāi)狀態(tài)。當(dāng)允許客戶機(jī)和服務(wù)器簡(jiǎn)單、高效地執(zhí)行會(huì)話的情況下,applet也可以啟動(dòng)客戶瀏覽器和服務(wù)器之間的連接。可以通過(guò)定制協(xié)議或標(biāo)準(zhǔn)(如 IIOP)進(jìn)行通信。

          (6) 對(duì)特殊的處理采用 MIME 類型過(guò)濾數(shù)據(jù),例如圖像轉(zhuǎn)換和服務(wù)器端包括(SSI)。

          (7) 將定制的處理提供給所有服務(wù)器的標(biāo)準(zhǔn)例行程序。例如,Servlet 可以修改如何認(rèn)證用戶。

          Servlet 的生命周期

            Servlet 的生命周期始于將它裝入 Web 服務(wù)器的內(nèi)存時(shí),并在終止或重新裝入 Servlet 時(shí)結(jié)束。

          (1) 初始化
          在下列時(shí)刻裝入 Servlet:
          =如果已配置自動(dòng)裝入選項(xiàng),則在啟動(dòng)服務(wù)器時(shí)自動(dòng)裝入
          =在服務(wù)器啟動(dòng)后,客戶機(jī)首次向 Servlet 發(fā)出請(qǐng)求時(shí)
          =重新裝入 Servlet 時(shí)
          裝入 Servlet 后,服務(wù)器創(chuàng)建一個(gè) Servlet 實(shí)例并且調(diào)用 Servlet 的 init() 方法。在初始化階段,Servlet 初始化參數(shù)被傳遞給 Servlet 配置對(duì)象。

          (2) 請(qǐng)求處理
          對(duì)于到達(dá)服務(wù)器的客戶機(jī)請(qǐng)求,服務(wù)器創(chuàng)建特定于請(qǐng)求的一個(gè)"請(qǐng)求"對(duì)象和一個(gè)"響應(yīng)"對(duì)象。服務(wù)器調(diào)用 Servlet 的 service() 方法,該方法用于傳遞"請(qǐng)求"和"響應(yīng)"對(duì)象。service() 方法從"請(qǐng)求"對(duì)象獲得請(qǐng)求信息、處理該請(qǐng)求并用"響應(yīng)"對(duì)象的方法以將響應(yīng)傳回客戶機(jī)。service() 方法可以調(diào)用其它方法來(lái)處理請(qǐng)求,例如 doGet()、doPost() 或其它的方法。

          (3) 終止
          當(dāng)服務(wù)器不再需要 Servlet, 或重新裝入 Servlet 的新實(shí)例時(shí),服務(wù)器會(huì)調(diào)用 Servlet 的 destroy() 方法。

            回復(fù)  更多評(píng)論
            
          # re: 面試題 2008-06-18 22:27 | BlueSunshine
          1 替換
          2 編碼轉(zhuǎn)換
          3 一個(gè)RuntimeException例子  回復(fù)  更多評(píng)論
            
          主站蜘蛛池模板: 灵璧县| 庄浪县| 梁山县| 河池市| 新竹县| 萍乡市| 波密县| 余江县| 乐陵市| 安乡县| 册亨县| 宝兴县| 东乡| 旅游| 互助| 平昌县| 舞阳县| 威海市| 垣曲县| 曲麻莱县| 于田县| 旺苍县| 阜宁县| 威海市| 思茅市| 土默特右旗| 额尔古纳市| 剑河县| 成安县| 平利县| 阳原县| 肥城市| 平南县| 石嘴山市| 连城县| 五河县| 井冈山市| 驻马店市| 南丹县| 于都县| 辽宁省|