[JAVA]ThreadLocal在servlet和filter中使用应该注意的问题

许多人会有一个疑问:servlet和filter到底是单例的还是多例的,如果是单例的他是怎么多线程访问的?其实关于servlet和filter他俩是单例还是多例我们在写的时候就会发现,没有写单例模式的代码。其实他两个东西在代码上是多例的,但是服务器容器会在运行项目的时候就将这两个东西实例化一个放到内存里面,每次执行都执行内存中已经实例化好的,其实这类似于单例,但是他又不会有单例模式在多线程时只有一个线程在执行这个类而其他线程等待上一个线程释放资源的情况。这种情况下static变量就会有线程安全的问题。

在servlet和filter中经常会使用全局变量来给其他类传递参数,按照上面说的,直接使用static肯定会出现线程安全的问题,为此我们只能采用迂回的方式去处理全局变量,然后就引入了ThreadLoacal这个类。注意:ThreadLocal并不是为了解决多线程的线程安全而创造的

我们在servlet和filter中使用ThreadLocal应当注意在servlet和filter每次执行完都要主动去销毁当前线程ThreadLocal里面的值,因为在多个用户访问的时候服务器容器会创建多个线程,这种情况下ThreadLocal会为每个线程复制一个对象,但是当线程处理完用户请求后,当前线程就被释放了,但是线程并没有销毁,再有新的访问请求到容器,容器会重新启用这个线程去处理请求,如果ThreadLocal中的值没有被销毁,那么他会是上次保留的值,造成数据混乱。比如存储了用户的信息一个用户登录了一个没登陆,没登陆的用户可能会通过ThreadLocal存储上上个用户的信息获得某些访问权限。下面用代码举一下在filter中使用ThreadLocal的例子:

1、Holder类(存储全局变量的ThreadLocal)

package com.roubsite.demo;

public class TestHolder {
	//contexts相当于一个Map,key是线程的id,val是你设置的值,这个值在当前线程中是随时可取的,相当于一个全局变量
	private final static ThreadLocal contexts = new ThreadLocal();

	/**
	 * 设置全局变量
	 * @param val
	 */
	public static void setString(String val) {
		contexts.set(val);
	}

	/**
	 * 获取全局变量的数据
	 * @return
	 */
	public static String getString() {
		return contexts.get();
	}

	/**
	 * 销毁当前线程记录的全局变量
	 */
	public static void distory() {
		contexts.remove();
	}
}

2、Filter(servlet类似)

package com.roubsite.demo;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class TestFilter implements Filter {

	@Override
	public void destroy() {
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		//注意:一定要是用try捕获异常,因为万一中间出现了错误也可以保证会执行finally里面的代码去销毁全局变量
		try {
			//代码
			TestHolder.setString("放置的全局变量");
		} finally {
			//保证销毁全局变量
			TestHolder.distory();
		}
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

}

 

你可能感兴趣的:(java,java,roubsite)