細心!用心!耐心!

          吾非文人,乃市井一俗人也,讀百卷書,跨江河千里,故申城一游; 一兩滴辛酸,三四年學業,五六點粗墨,七八筆買賣,九十道人情。

          BlogJava 聯系 聚合 管理
            1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks
          無論如何,要編寫一個多執行緒安全(thread-safe)的程式總是困難的,為了使用的共用資源,您必須小心的對共用資源進行同步,同步帶來一定的效能延遲,而另一方面,在處理同步的時候,又要注意物件的鎖定與釋放,避免產生死結,種種因素都使得編寫多執行緒程式變得困難。

          Thread-Specific Storage模式嘗試從另一個角度來解釋多執行緒共用資源的問題,其思考點很簡單,即然共用資源這麼困難,那麼就乾脆不要共用,何不為每個執行緒創造一個資源的複本,將每一個執行緒存取資料的行為加以隔離,其實現的方法,就是給予每一個執行緒一個特定空間來保管該執行緒所獨享的資源,也因此而稱之為 Thread- Specific Storage模式。

          在Java中可以使用java.lang.ThreadLocal來實現這個模式,這個類別是從1.2之後開始提供,不過先來看看,如何自行實現一個簡單的ThreadLocal類別:
          • ThreadLocal.java
          import java.util.*;

          public class ThreadLocal {
          private Map storage =
          Collections.synchronizedMap(new HashMap());

          public Object get() {
          Thread current = Thread.currentThread();
          Object o = storage.get(current);

          if(o == null && !storage.containsKey(current)) {
          o = initialValue();
          storage.put(current, o);
          }

          return o;
          }

          public void set(Object o) {
          storage.put(Thread.currentThread(), o);
          }

          public Object initialValue() {
          return null;
          }
          }

          可以看到程式中使用執行緒本身作為key值,並將所獲得的資源放在Map物件中,如果第一次使用get(),也配置一個空間給執行緒,而 initialValue()可以用來設定什麼樣的初值要先儲存在這個空間中,在這邊先簡單的設定為null。

          現在假設有一個原先在單執行緒環境下的資源SomeResource,現在考慮要該其在多執行緒環境下使用,若不想考慮複雜的執行緒共用互斥問題,此時可以使用ThreadLocal類別來使用SomeResource,例如:
          • Resource.java
          public class Resource {
          private static final ThreadLocal threadLocal =
          new ThreadLocal();

          public static SomeResource getResource() {
          SomeResource resource =
          (SomeResource) threadLocal.get();

          if(resource == null) {
          resource = new SomeResource();
          threadLocal.set(resource);
          }

          return resource;
          }
          }

          上面所實作的ThreadLocal類別只是一個簡單的示範,您可以使用java.lang.ThreadLocal來實現Thread- Specific Storage模式,以獲得更好的效能,在這邊簡單的示範一個Log程式,它可以記錄每個執行緒的活動,所使用的是 java.util.logging中的類別:
          • SimpleThreadLogger.java
          import java.io.*;
          import java.util.logging.*;

          public class SimpleThreadLogger {
          private static final ThreadLocal threadLocal =
          new ThreadLocal();

          public static void log(String msg) {
          getThreadLogger().log(Level.INFO, msg);
          }

          private static Logger getThreadLogger() {
          Logger logger = (Logger) threadLocal.get();

          if(logger == null) {
          try {
          logger = Logger.getLogger(
          Thread.currentThread().getName());
          // Logger 預設是在主控臺輸出
          // 我們加入一個檔案輸出的Handler
          // 它會輸出XML的記錄文件
          logger.addHandler(
          new FileHandler(
          Thread.currentThread().getName()
          + ".log"));
          }
          catch(IOException e) {}

          threadLocal.set(logger);
          }

          return logger;
          }
          }

          可以使用下面這個程式來測試:
          • LoggerTest.java
          public class LoggerTest {
          public static void main(String[] args) {
          new TestThread("thread1").start();
          new TestThread("thread2").start();
          new TestThread("thread3").start();
          }
          }

          class TestThread extends Thread {
          public TestThread(String name) {
          super(name);
          }

          public void run() {
          for(int i = 0; i < 10; i++) {
          SimpleThreadLogger.log(getName() +
          ": message " + i);
          try {
          Thread.sleep(1000);
          }
          catch(Exception e) {
          SimpleThreadLogger.log(e.toString());
          }
          }
          }
          }

          執行LoggerTest可以在主控臺上看到輸出,並可以在同一目錄下找到三個log檔,分別記錄了三個執行緒的活動,透過 ThreadLocal,不用撰寫複雜的執行緒共用互斥邏輯。

          Thread-Specific Storage模式的意義之一,就是「有時不共用是好的」,如果共用會產生危險,那就不要共用,當然,這種方式所犧牲掉的就是空間,您必須為每一個執行緒保留它們獨立的空間,這是一種以空間換取時間與安全性的方法。
          posted on 2007-04-17 10:59 張金鵬 閱讀(672) 評論(0)  編輯  收藏 所屬分類: 多執行緒模式
          主站蜘蛛池模板: 邵阳市| 夏津县| 甘孜县| 湘潭县| 赤壁市| 屯门区| 景德镇市| 襄樊市| 黎川县| 舟山市| 五莲县| 奉贤区| 渝北区| 惠东县| 宽城| 韶山市| 互助| 南乐县| 小金县| 天镇县| 滨州市| 石渠县| 金平| 莱州市| 容城县| 太谷县| 弋阳县| 沁阳市| 贵港市| 习水县| 贵定县| 丹凤县| 东兰县| 汤阴县| 东至县| 龙胜| 新津县| 应城市| 徐水县| 洪雅县| 乐清市|