ThreadLocal即线程本地化变量,使用场合主要解决多线程中数据因并发产生不一致问题。ThreadLocal为每个线程的中并发访问的数据提供一个副本,通过访问副本来运行业务,这样的结果是耗费了内存,但是大大减少了线程同步所带来性能消耗,也减少了线程并发控制的复杂度。
下面的例子是实现日志记录的功能,每个线程都有对应的日志文件。
1 package com.thread.test; 2 3 import java.io.IOException; 4 import java.util.logging.FileHandler; 5 import java.util.logging.Level; 6 import java.util.logging.Logger; 7 8 public class ThreadLogger { 9 10 private static final ThreadLocal<Logger> threadLocal = new ThreadLocal<Logger>(); 11 12 public static void log(String msg){ 13 getThreadLogger().log(Level.INFO,msg); 14 } 15 16 /** 17 * 从ThreadLocal中获取当前线程对应的Logger对象,如果ThreadLocal中没有保存当前线程对应的Logger对象 18 * 则新建一个Logger对象,并放入ThreadLocal中。 19 * @return 20 */ 21 public static Logger getThreadLogger(){ 22 Logger logger = threadLocal.get(); // 获取当前线程的Logger对象 23 if(logger == null){ 24 logger = Logger.getLogger(Thread.currentThread().getName()); 25 try { 26 logger.addHandler( new FileHandler(Thread.currentThread().getName() + ".log")); 27 } catch (SecurityException e) { 28 e.printStackTrace(); 29 } catch (IOException e) { 30 e.printStackTrace(); 31 } 32 33 threadLocal.set(logger); // 添加副本 34 } 35 36 return logger; 37 } 38 }
1 package com.thread.test; 2 3 public class Main { 4 5 6 public static void main(String[] args) { 7 /* MyThread myThread = new MyThread(); 8 new Thread(myThread).start(); 9 new Thread(myThread).start(); */ 10 11 new TestThread("t1").start(); 12 new TestThread("t2").start(); 13 new TestThread("t3").start(); 14 } 15 16 } 17 18 class TestThread extends Thread{ 19 20 public TestThread(String name) { 21 super(name); 22 } 23 24 @Override 25 public void run() { 26 for( int i=1;i<5;i++){ 27 ThreadLogger.log(getName()+":message"+i); 28 } 29 } 30 }
---------------------------------------------------- 誑逩の蝸犇 : I believe Nothing is impossible. ----------------------------------------------------