demo:使用户可以判断自己访问站点的排名
// 配置拦截器用于拦截所有的访问请求
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="demo.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
public class MyInterceptor extends HandlerInterceptorAdapter {
private static final AtomicInteger couter;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 为每个访问的线程排上序号
GlobalThreadLocalUtil.setNum("序号:" + couter.incrementAndGet());
return super.preHandle(request, response, handler);
}
}
public class GlobalThreadLocalUtil {
private static final ThreadLocal<String> TL = new ThreadLocal<>();
public static void setNum(String num) {
String num = getNum();
if (num != null) {
TL.remove();
}
TL.set(num);
}
public static String getNum() {
return TL.get();
}
}
以上案例中GlobalThreadLocalUtil中的ThreadLocal实例TL会以自己(TL实例)为key,num为value,把键值对存入当前线程中,然后当该线程用该num值时候可以国通GlobalThreadLocalUtil.getNum()直接获取,这时获取的num是线程隔离的,获取的是当前线程的值,原因见源码:
总结:
ThreadLocal为每个线程都提供了变量的副本,使得每个线程在某一时间访问到的并非同一个对象,这样就隔离了多个线程对数据的数据共享
与Synchonized的对照:
ThreadLocal和Synchonized都用于解决多线程并发访问。
synchronized是利用锁的机制,使变量或代码块在某一时该仅仅能被一个线程访问,它用于在多个线程间通信时可以获得数据共享