1.ThreadLocal 的定义和作用
ThreadLocal和Synchonized都用于解决多线程并发访问。但是ThreadLocal与synchronized有本质的区别。Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。Synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。
一句话理解ThreadLocal,向ThreadLocal里面存东西就是向它里面的Map存东西的,然后ThreadLocal把这个Map挂到当前的线程底下,这样Map就只属于这个线程了。
2.Thread,ThreadLocal,ThreadLocalMap 三者关系
一个线程Thread中只有一个ThreadLocalMap,一个ThreadLocalMap中可以有多个ThreadLocal对象,其中一个ThreadLocal对象对应一个ThreadLocalMap中的一个Entry(也就是说:一个Thread可以依附有多个ThreadLocal对象)。
具体原理,请参考大神链接:https://blog.csdn.net/cowbin2012/article/details/89740996
========================================================================================
3.场景应用
public class LogManager
{
private static ThreadPoolManager threadPool =ThreadPoolManager.getInstance("logManager");
private static ThreadLocal local = new ThreadLocal();
/**
* 初始化
* @see [类、类#方法、类#成员]
*/
public static void initialize()
{
SystemLogBean log = new SystemLogBean();
local.set(log);
}
/**
* 实例销毁
* @see [类、类#方法、类#成员]
*/
public static void destory()
{
local.remove();
}
public static SystemLogBean getLog()
{
SystemLogBean log = (SystemLogBean) local.get();
if (log == null)
{
log = new SystemLogBean();
setLog(log);
}
return log;
}
public static void setLog(SystemLogBean log)
{
local.set(log);
}
/**
* 写入日志表
* @see [类、类#方法、类#成员]
*/
public static void logging()
{
SystemLogBean log = (SystemLogBean) local.get();
// 设置业务类型的业务可以写入操作日志
if (..........)
{
threadPool.addTask(new LogWriter(log));
}
}
}
====================================================================================
**线程管理类:**
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Queue;
import java.util.ResourceBundle;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 线程池管理类
*
* @author wKF52599
* @version [NGESHOP V1.0, Feb 17, 2012]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
public class ThreadPoolManager
{
private static Hashtable<String, ThreadPoolManager> tb = new Hashtable<String, ThreadPoolManager>();
// 线程池维护线程的最少数量
private final static int CORE_POOL_SIZE = 30;
// 线程池维护线程的最大数量
private final static int MAX_POOL_SIZE = 60;
// 线程池维护线程所允许的空闲时间
private final static int KEEP_ALIVE_TIME = 180;
// 线程池所使用的缓冲队列大小
private final static int WORK_QUEUE_SIZE = 10;
// 请求Request缓冲队列
public Queue<Runnable> msgQueue = new LinkedList<Runnable>();
// 访问请求Request缓存的调度线程
final Runnable accessBufferThread = new Runnable()
{
public void run()
{
// 查看是否有待定请求,如果有,则添加到线程池中
if (hasMoreAcquire())
{
System.out.println("有待定请求,添加到线程池中...");
// SearchTask task = ( SearchTask ) msgQueue.poll();
threadPool.execute(msgQueue.poll());
}
}
};
// handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序
final RejectedExecutionHandler handler = new RejectedExecutionHandler()
{
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor)
{
// System.out.println(r + " request 放入队列中重新等待执行 " + r);
msgQueue.offer(r);
}
};
// 管理线程池
final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME,
TimeUnit.SECONDS, new ArrayBlockingQueue(WORK_QUEUE_SIZE), this.handler);
// 调度线程池
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
// 定时调度
final ScheduledFuture taskHandler = scheduler.scheduleAtFixedRate(accessBufferThread, 0, 1, TimeUnit.SECONDS);
/**
* 根据key取得对应实例
*
* @param key
* @return
*/
public static synchronized ThreadPoolManager getInstance(String key)
{
ThreadPoolManager obj = tb.get(key);
if (obj == null)
{
// System.out.println("new thread pool :" + key);
obj = new ThreadPoolManager();
tb.put(key, obj);
//new ThreadPoolManager().poolMonitor();
}
return obj;
}
private ThreadPoolManager()
{
}
private boolean hasMoreAcquire()
{
//System.err.println("待执行数量:"+msgQueue.size());
return !msgQueue.isEmpty();
}
public void addTask(Runnable task)
{
//System.err.println("目前线程池活动线程数量:"+threadPool.getActiveCount());
// System.out.println("准备处理线程..."+task);
threadPool.execute(task);
}
/**
* 判断线程池是否已满
* @return true 已满,false 未满
*/
public boolean isPoolFull(){
return threadPool.getActiveCount()>=MAX_POOL_SIZE;
}
public ThreadPoolExecutor getThreadPool(){
return threadPool;
}
/*
private void poolMonitor(){
new Thread() {
public void run() {
while(true){
try {
sleep(1*1000L);
ThreadPoolExecutor t=ThreadPoolManager.getInstance("tmallNotify").getThreadPool();
System.out.println("monitor>>>threadPool.getActiveCount():"+t.getActiveCount()+" , MAX_POOL_SIZE:"+MAX_POOL_SIZE+", QUENE_SIZE:"+t.getQueue().size());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}*/
public <V> Future<V> submit(Callable<V> task)
{
return threadPool.submit(task);
}
}