一.简介
JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal并不是一个Thread,而是Thread的局部变量。
二.实例
以下通过自定义
HandlerInterceptor 实现日志记录,其中包含threadlocal使用
springmvc配置文件拦截器配置:
<mvc:interceptor> <mvc:mapping path="/**" /> <mvc:exclude-mapping path="${adminPath}/**"/> <bean class="com.rcz.platform.framework.sys.modules.sys.interceptor.ToperateLogInterceptor" /> </mvc:interceptor>
代码:
import com.rcz.platform.framework.sys.common.service.BaseService; import com.rcz.platform.framework.sys.common.utils.DateUtils; import com.rcz.platform.framework.sys.modules.sys.utils.LogUtil; import org.springframework.core.NamedThreadLocal; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.text.SimpleDateFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Created by Administrator on 2018/1/31. */ public class ToperateLogInterceptor implements HandlerInterceptor {
/** * 日志对象 */ protected Logger logger = LoggerFactory.getLogger(getClass());
private static final ThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<Long>("ThreadLocal StartTime"); public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (logger.isDebugEnabled()){ long beginTime = System.currentTimeMillis();//1、开始时间 startTimeThreadLocal.set(beginTime); //线程绑定变量(该数据只有当前请求的线程可见) logger.debug("开始计时: {} URI: {}", new SimpleDateFormat("hh:mm:ss.SSS") .format(beginTime), request.getRequestURI()); } return true; } public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { if (modelAndView != null){ logger.info("ViewName: " + modelAndView.getViewName()); } } public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 保存日志 LogUtil.saveLog(request, null); // 打印JVM信息。 if (logger.isDebugEnabled()){ long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量(开始时间) long endTime = System.currentTimeMillis(); //2、结束时间 logger.debug("计时结束:{} 耗时:{} URI: {} 最大内存: {}m 已分配内存: {}m 已分配内存中的剩余空间: {}m 最大可用内存: {}m", new SimpleDateFormat("hh:mm:ss.SSS").format(endTime), DateUtils.formatDateTime(endTime - beginTime), request.getRequestURI(), Runtime.getRuntime().maxMemory()/1024/1024, Runtime.getRuntime().totalMemory()/1024/1024, Runtime.getRuntime().freeMemory()/1024/1024, (Runtime.getRuntime().maxMemory()-Runtime.getRuntime().totalMemory()+Runtime.getRuntime().freeMemory())/1024/1024); //删除线程变量中的数据,防止内存泄漏 startTimeThreadLocal.remove(); } } }
三.总结