线程与线程之间是相互隔离
package com.fan.threadlocal;
/**
* @author およそ神
* @version JDK 1.8
*/
public class Concurrent {
private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
public static void main(String[] args)throws Exception {
Thread t1 = new Thread(() -> {
System.out.println(threadLocal.get());
threadLocal.set(0);
System.out.println(threadLocal.get());
});
Thread t2 = new Thread(() -> {
System.out.println(threadLocal.get());
threadLocal.set(1);
System.out.println(threadLocal.get());
});
t1.start();
t1.join();
t2.start();
}
}
执行结果:
null
0
null
1
由执行结果可以看出threadlocal的线程与线程之间是相互隔离的。
用来做权限验证
拦截器
package com.fan.testtreadlocal.filter;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author およそ神
* @version JDK 1.8
*/
@Component
public class MyFilter extends OncePerRequestFilter {
public static ThreadLocal<Integer> auth = new ThreadLocal<Integer>();
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
auth.set(0);
if (httpServletRequest.getHeader("Authorization").equals("1")) {
auth.set(1);
}
doFilter(httpServletRequest,httpServletResponse,filterChain);
}
}
启动和控制
package com.fan.testtreadlocal;
import com.fan.testtreadlocal.filter.MyFilter;
import com.fan.testtreadlocal.filter.ResponseVO;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@Controller
@SpringBootApplication
@RestController
public class TestTreadLocalApplication {
public static void main(String[] args) {
SpringApplication.run(TestTreadLocalApplication.class, args);
}
@GetMapping("/")
public ResponseVO<String> index() {
try {
if (MyFilter.auth.get()==1) return ResponseVO.okHasData("有权限!");
else return ResponseVO.okHasData("没有权限!");
} finally {
MyFilter.auth.remove();
}
}
}
threadlocal 常用的3个方法get,set和remove
threadlocal里面有一个静态的entry class 继承了WeakReference弱引用!
弱引用就很容易被下次gc清理掉,从而减少性能开销,如果key对entry强引用key是threadlocal可能是static就一直不会被gc,value也不会被gc,就会造成内存泄露!