徹底理解Java中的ThreadLocal-創(chuàng)新互聯(lián)

 ThreadLocal是什么

成都創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的縉云網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

  早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal為解決多線程程序的并發(fā)問(wèn)題提供了一種新的思路。使用這個(gè)工具類可以很簡(jiǎn)潔地編寫出優(yōu)美的多線程程序。

  當(dāng)使用ThreadLocal維護(hù)變量時(shí),ThreadLocal為每個(gè)使用該變量的線程提供獨(dú)立的變量副本,所以每一個(gè)線程都可以獨(dú)立地改變自己的副本,而不會(huì)影響其它線程所對(duì)應(yīng)的副本。

  從線程的角度看,目標(biāo)變量就象是線程的本地變量,這也是類名中“Local”所要表達(dá)的意思。

  所以,在Java中編寫線程局部變量的代碼相對(duì)來(lái)說(shuō)要笨拙一些,因此造成線程局部變量沒(méi)有在Java開(kāi)發(fā)者中得到很好的普及。

ThreadLocal的接口方法

ThreadLocal類接口很簡(jiǎn)單,只有4個(gè)方法,我們先來(lái)了解一下:

  • void set(Object value)設(shè)置當(dāng)前線程的線程局部變量的值。
  • public Object get()該方法返回當(dāng)前線程所對(duì)應(yīng)的線程局部變量。
  • public void remove()將當(dāng)前線程局部變量的值刪除,目的是為了減少內(nèi)存的占用,該方法是JDK 5.0新增的方法。需要指出的是,當(dāng)線程結(jié)束后,對(duì)應(yīng)該線程的局部變量將自動(dòng)被垃圾回收,所以顯式調(diào)用該方法清除線程的局部變量并不是必須的操作,但它可以加快內(nèi)存回收的速度。
  • protected Object initialValue()返回該線程局部變量的初始值,該方法是一個(gè)protected的方法,顯然是為了讓子類覆蓋而設(shè)計(jì)的。這個(gè)方法是一個(gè)延遲調(diào)用方法,在線程第1次調(diào)用get()或set(Object)時(shí)才執(zhí)行,并且僅執(zhí)行1次。ThreadLocal中的缺省實(shí)現(xiàn)直接返回一個(gè)null。

  值得一提的是,在JDK5.0中,ThreadLocal已經(jīng)支持泛型,該類的類名已經(jīng)變?yōu)門hreadLocal<T>。API方法也相應(yīng)進(jìn)行了調(diào)整,新版本的API方法分別是void set(T value)、T get()以及T initialValue()。

  ThreadLocal是如何做到為每一個(gè)線程維護(hù)變量的副本的呢?其實(shí)實(shí)現(xiàn)的思路很簡(jiǎn)單:在ThreadLocal類中有一個(gè)Map,用于存儲(chǔ)每一個(gè)線程的變量副本,Map中元素的鍵為線程對(duì)象,而值對(duì)應(yīng)線程的變量副本。我們自己就可以提供一個(gè)簡(jiǎn)單的實(shí)現(xiàn)版本:

package com.test; 
public class TestNum { 
 // ①通過(guò)匿名內(nèi)部類覆蓋ThreadLocal的initialValue()方法,指定初始值 
 private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() { 
  public Integer initialValue() { 
   return 0; 
  } 
 }; 
 // ②獲取下一個(gè)序列值 
 public int getNextNum() { 
  seqNum.set(seqNum.get() + 1); 
  return seqNum.get(); 
 } 
 public static void main(String[] args) { 
  TestNum sn = new TestNum(); 
  // ③ 3個(gè)線程共享sn,各自產(chǎn)生序列號(hào) 
  TestClient t1 = new TestClient(sn); 
  TestClient t2 = new TestClient(sn); 
  TestClient t3 = new TestClient(sn); 
  t1.start(); 
  t2.start(); 
  t3.start(); 
 } 
 private static class TestClient extends Thread { 
  private TestNum sn; 
  public TestClient(TestNum sn) { 
   this.sn = sn; 
  } 
  public void run() { 
   for (int i = 0; i < 3; i++) { 
    // ④每個(gè)線程打出3個(gè)序列值 
    System.out.println("thread[" + Thread.currentThread().getName() + "] --> sn[" 
       + sn.getNextNum() + "]"); 
   } 
  } 
 } 
} 

網(wǎng)站標(biāo)題:徹底理解Java中的ThreadLocal-創(chuàng)新互聯(lián)
當(dāng)前URL:http://muchs.cn/article28/cspscp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、云服務(wù)器、關(guān)鍵詞優(yōu)化、響應(yīng)式網(wǎng)站、網(wǎng)站改版、手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)