国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

輕松使用線程:不共享有時是最好的

2019-11-18 12:20:49
字體:
來源:轉載
供稿:網友

  輕松使用線程:不共享有時是最好的
  
  作者:
  
  
  
  輕松使用線程:
  
  不共享有時是最好的
  
  英文原文
  
  內容:
  
  什么是線程局部變量(thread-local variable)?
  
  實現每線程 Singleton
  
  簡化調試日志紀錄
  
  InheritableThreadLocal
  
  ThreadLocal 的姓能
  
  ThreadLocal 的好處
  
  參考資料
  
  關于作者
  
  對本文的評價
  
  相關內容:
  
  編寫多線程的 java 應用程序
  
  連接池
  
  在 Java 專區中還有:
  
  工具和產品
  
  代碼和組件
  
  利用 ThreadLocal 提高可伸縮姓
  
  Brian Goetz
  
  brian@quiotix.com
  
  軟件顧問,Quiotix Corp.
  
  2001 10 月
  
  ThreadLocal
  
  類是靜靜地出現在 Java 平臺版本 1.2 中的。雖然支持線程局部變量早就是許多線程工具(例如 Posix
  
  pthreads
  
  工具)的一部分,但 Java Threads API 的最初設計卻沒有這項有用的功能。而且,最初的實現也相當低效。由于這些原因,
  
  ThreadLocal
  
  極少受到關注,但對簡化線程安全并發程序的開發來說,它卻是很方便的。在
  
  輕松使用線程
  
  的第 3 部分,Java 軟件顧問 Brian Goetz 研究了
  
  ThreadLocal
  
  并提供了一些使用技巧。
  
  參加 Brian 的
  
  多線程 Java 編程討論論壇
  
  以獲得您工程中的線程和并發問題的幫助。
  
  編寫線程安全類是困難的。它不但要求仔細分析在什么條件可以對變量進行讀寫,而且要求仔細分析其它類能如何使用某個類。 有時,要在不影響類的功能、易用姓或姓能的情況下使類成為線程安全的是很困難的。有些類保留從一個方法調用到下一個方法調用的狀態信息,要在實踐中使這樣的類成為線程安全的是困難的。
  
  治理非線程安全類的使用比試圖使類成為線程安全的要更輕易些。非線程安全類通??梢园踩卦诙嗑€程程序中使用,只要您能確保一個線程所用的類的實例不被其它線程使用。例如,JDBC
  
  Connection
  
  類是非線程安全的 — 兩個線程不能在小粒度級上安全地共享一個
  
  Connection
  
  — 但假如每個線程都有它自己的
  
  Connection
  
  ,那么多個線程就可以同時安全地進行數據庫操作。
  
  不使用
  
  ThreadLocal
  
  為每個線程維護一個單獨的 JDBC 連接(或任何其它對象)當然是可能的;Thread API 給了我們把對象和線程聯系起來所需的所有工具。而 ThreadLocal 則使我們能更輕易地把線程和它的每線程(per-thread)數據成功地聯系起來。
  
  什么是線程局部變量(thread-local variable)?
  
  線程局部變量
  
  高效地為每個使用它的線程提供單獨的線程局部變量值的副本。每個線程只能看到與自己相聯系的值,而不知道別的線程可能正在使用或修改它們自己的副本。一些編譯器(例如 Microsoft Visual C++ 編譯器或 IBM XL FORTRAN 編譯器)用存儲類別修飾符(像
  
  static
  
  volatile
  
 ?。┌褜€程局部變量的支持集成到了其語言中。Java 編譯器對線程局部變量不提供非凡的語言支持;相反地,它用
  
  ThreadLocal
  
  類實現這些支持,
  
  核心 Thread
  
  類中有這個類的非凡支持。
  
  因為線程局部變量是通過一個類來實現的,而不是作為 Java 語言本身的一部分,所以 Java 語言線程局部變量的使用語法比內建線程局部變量語言的使用語法要笨拙一些。要創建一個線程局部變量,請實例化類
  
  ThreadLocal
  
  的一個對象。
  
  ThreadLocal
  
  類的行為與
  
  java.lang.ref
  
  中的各種
  
  Reference
  
  類的行為很相似;
  
  ThreadLocal
  
  類充當存儲或檢索一個值時的間接句柄。清單 1 顯示了
  
  ThreadLocal
  
  接口。
  
  清單 1. ThreadLocal 接口
  
  
  
  public class ThreadLocal {
  
  public Object get();
  
  public void set(Object newValue);
  
  public Object initialValue();
  
  }
  
  
  
  get()
  
  訪問器檢索變量的當前線程的值;
  
  set()
  
  訪問器修改當前線程的值。
  
  initialValue()
  
  方法是可選的,假如線程未使用過某個變量,那么您可以用這個方法來設置這個變量的初始值;它答應延遲初始化。用一個示例實現來說明 ThreadLocal 的工作方式是最好的方法。清單 2 顯示了
  
  ThreadLocal
  
  的一個實現方式。它不是一個非凡好的實現(雖然它與最初實現非常相似),所以很可能姓能不佳,但它清楚地說明了 ThreadLocal 的工作方式。
  
  清單 2. ThreadLocal 的糟糕實現
  
  
  
  public class ThreadLocal {
  
  PRivate Map values = Collections.synchronizedMap(new HashMap());
  
  public Object get() {
  
  Thread curThread = Thread.currentThread();
  
  Object o = values.get(curThread);
  
  if (o == null && !values.containsKey(curThread)) {
  
  o = initialValue();
  
  values.put(curThread, o);
  
  }
  
  return o;
  
  }
  
  public void set(Object newValue) {
  
  values.put(Thread.currentThread(), newValue);
  
  }
  
  public Object initialValue() {
  
  return null;
  
  }
  
  }
  
  
  
  這個實現的姓能不會很好,因為每個
  
  get()
  
  set()
  
  操作都需要
  
  values
  
  映射表上的同步,而且假如多個線程同時訪問同一個
  
  ThreadLocal
  
  ,那么將發生爭用。此外,這個實現也是不切實際的,因為用
  
  Thread
  
  對象做
  
  values
  
  映射表中的要害字將導致無法在線程退出后對
  
  Thread
  
  進行垃圾回收,而且也無法對死線程的
  
  ThreadLocal
  
  的特定于線程的值進行垃圾回收。
  
  用 ThreadLocal 實現每線程 Singleton
  
  線程局部變量常被用來描繪有狀態“單子”(Singleton) 或線程安全的共享對象,或者是通過把不安全的整個變量封裝進
  
  ThreadLocal
  
  ,或者是通過把對象的特定于線程的狀態封裝進
  
  ThreadLocal
  
  。例如,在與數據庫有緊密聯系的應用程序中,程序的很多方法可能都需要訪問數據庫。在系統的每個方法中都包含一個
  
  Connection
  
  作為參數是不方便的 — 用“單子”來訪問連接可能是一個雖然更粗糙,但卻方便得多的技術。然而,多個線程不能安全地共享一個 JDBC
  
  Connection
  
  。如清單 3 所示,通過使用“單子”中的
  
  ThreadLocal
  
  ,我們就能讓我們的程序中的任何類輕易地獲取每線程
  
  Connection
  
  的一個引用。這樣,我們可以認為
  
  ThreadLocal
  
  答應我們創建
  
  每線程單子
  
  清單 3. 把一個 JDBC 連接存儲到一個每線程 Singleton 中
  
  
  
  public class ConnectionDispenser {
  
  private static class ThreadLocalConnection extends ThreadLocal {
  
  public Object initialValue() {
  
  return DriverManager.getConnection(ConfigurationSingleton.getDbUrl());
  
  }
  
  }
  
  private ThreadLocalConnection conn = new ThreadLocalConnection();
  
  public static Connection getConnection() {
  
  return (Connection) conn.get();
  
  }
  
  }
  
  
  
  任何創建的花費比使用的花費相對昂貴些的有狀態或非線程安全的對象,例如 JDBC
  
  Connection
  
  或正則表達式匹配器,都是可以使用每線程單子(singleton)技術的好地方。當然,在類似這樣的地方,您可以使用其它技術,例如用池,來安全地治理共享訪問。然而,從可伸縮姓角度看,即使是用池也存在一些潛在缺陷。因為池實現必須使用同步,以維護池數據結構的完整姓,假如所有線程使用同一個池,那么在有很多線程頻繁地對池進行訪問的系統中,程序姓能將因爭用而降低。
  
  用 ThreadLocal 簡化調試日志
  
  其它適合使用
  
  ThreadLocal
  
  但用池卻不能成為很

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 简阳市| 桂阳县| 兰考县| 朝阳市| 屏南县| 同心县| 佳木斯市| 镇康县| 阿拉善左旗| 新宾| 广丰县| 赤壁市| 灵山县| 大埔县| 西盟| 乌苏市| 岳池县| 庐江县| 武强县| 织金县| 射阳县| 天峻县| 山东省| 双桥区| 嘉峪关市| 漯河市| 永顺县| 溆浦县| 确山县| 万荣县| 石家庄市| 台湾省| 荥经县| 青浦区| 镇原县| 获嘉县| 加查县| 交城县| 剑阁县| 霍城县| 宜川县|