ThreadLocal场景之log日志

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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值