ThreadLocal表明線程局部變量,就是爲每個使用該變量的線程都提供一個變量值的副本,使每個線程均可以獨立地改變本身的副本,而不會和其它線程副本衝突。java
它能夠看作是一個以ThreadLocal對象爲鍵、任意對象爲值的存儲結構。這個結構被附帶在線程上,也就是說一個線程能夠根據一個ThreadLocal對象查詢到綁定到這個線程上的一個值。
下面是它的用法示例:ide
class Account { private ThreadLocal<String> name = new ThreadLocal<>(); public Account(String string) { this.name.set(string); } public String getName() { return name.get(); } public void setName(String string) { name.set(string); } } class MyTest extends Thread { private Account account; public MyTest(Account account, String name) { super(name); this.account = account; } public void run() { for (int i=0;i<5;i++) { if (i == 2) { account.setName(getName()); } System.out.println(account.getName() + "帳戶的i的值:" + i); } } } public class ThreadLocalTest { public static void main(String[] args) { Account at = new Account("線程Main"); //main線程中thradlocal中的變量值 System.out.println(at.getName()); new MyTest(at, "線程甲").start(); new MyTest(at, "線程乙").start(); } }
運行結果以下:this
線程Main null帳戶的i的值:0 null帳戶的i的值:1 線程甲帳戶的i的值:2 線程甲帳戶的i的值:3 線程甲帳戶的i的值:4 null帳戶的i的值:0 null帳戶的i的值:1 線程乙帳戶的i的值:2 線程乙帳戶的i的值:3 線程乙帳戶的i的值:4
上面程序中變量的關係以下:線程
下面是一個使用ThreadLocal來實現計時功能的類:code
public class Profiler { private static final ThreadLocal<Long> TIME_THREADLOCAL = new ThreadLocal<Long>(){ @Override protected Long initialValue() { return System.currentTimeMillis(); } }; public static final void begin() { TIME_THREADLOCAL.set(System.currentTimeMillis()); } public static final long end() { return System.currentTimeMillis() - TIME_THREADLOCAL.get(); } public static void main(String[] args) throws Exception{ Profiler.begin(); TimeUnit.SECONDS.sleep(1); System.out.println("Cost: " + Profiler.end() + " mills"); } }
輸出:對象
Cost: 1009 mills