package org.test; public class ThreadLocalTest { public static void main(String[] args) { User user = new User(new ThreadLocal<String>()); Book book = new Book(); Thread t1 = new Thread(new UnSafeRunnable(user, "pat", book)); Thread t2 = new Thread(new UnSafeRunnable(user, "zhenglong", book)); t1.start(); t2.start(); } } class Book { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } class User { private ThreadLocal<String> name; public User(ThreadLocal<String> name) { this.name = name; } public String getName() { return name.get(); } public void setName(String names) { name.set(names); } } class UnSafeRunnable implements Runnable { private User user; private String name; private Book book; public UnSafeRunnable(User user, String name, Book book) { this.user = user; this.name = name; this.book = book; } @Override public void run() { user.setName(name); book.setName(name); try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.err.println(user.getName() + "user"); System.err.println(book.getName() + "book"); } }
我的工具类: 在拦截起中间 将属性保存到ThreadLocal中间去,确保在单个线程中间的全部流程中都可以获取到我们复制的属性 这也是ThreadLocal的最大的用途
package com.chelement.core.common; import com.chelement.core.common.vo.ChannelUserTokenDetailVO; import com.chelement.core.common.vo.ChelementUserTokenDetailVO; import com.chelement.core.common.vo.CustomerTokenDetailVO; /** * 权限工具类for 缓存 * * @author pat * */ public class AccessControllerUtil { private static ThreadLocal<ChannelUserTokenDetailVO> threadLocal_channel_user = new ThreadLocal<ChannelUserTokenDetailVO>(); private static ThreadLocal<ChelementUserTokenDetailVO> threadLocal_chelement_user = new ThreadLocal<ChelementUserTokenDetailVO>(); private static ThreadLocal<CustomerTokenDetailVO> threadLocal_customer_user = new ThreadLocal<CustomerTokenDetailVO>(); private AccessControllerUtil() { } public static ChannelUserTokenDetailVO getChannelUserDetailFromThreadLocal() { return threadLocal_channel_user.get(); } public static void setChannelUserDetailFromThreadLocal(ChannelUserTokenDetailVO newValue) { threadLocal_channel_user.set(newValue); } public static void removeChannelUserDetailFromThreadLocal() { threadLocal_channel_user.remove(); } public static ChelementUserTokenDetailVO getChelementUserDetailFromThreadLocal() { return threadLocal_chelement_user.get(); } public static void setChelementUserDetailFromThreadLocal(ChelementUserTokenDetailVO newValue) { threadLocal_chelement_user.set(newValue); } public static void removeChelementUserDetailFromThreadLocal() { threadLocal_chelement_user.remove(); } public static CustomerTokenDetailVO getCustomerDetailFromThreadLocal() { return threadLocal_customer_user.get(); } public static void setCustomerDetailFromThreadLocal(CustomerTokenDetailVO newValue) { threadLocal_customer_user.set(newValue); } public static void removeCustomerDetailFromThreadLocal() { threadLocal_customer_user.remove(); } }
package com.chelement.core.common; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.alibaba.fastjson.JSON; import com.chelement.business.enums.permission.SysRoleEnum; import com.chelement.core.channelManagement.dal.domain.Channel; import com.chelement.core.channelManagement.dal.domain.ChannelUser; import com.chelement.core.channelManagement.service.ChannelService; import com.chelement.core.channelManagement.service.ChannelUserService; import com.chelement.core.common.vo.BaseTokenDetailVO; import com.chelement.core.common.vo.ChannelUserTokenDetailVO; import com.chelement.core.common.vo.ChelementUserTokenDetailVO; import com.chelement.core.common.vo.CustomerTokenDetailVO; import com.chelement.core.customerManagement.service.CustomerService; import com.chelement.core.exceptions.BizException; import com.chelement.core.houseManagement.dal.domain.Community; import com.chelement.core.houseManagement.service.CommunityService; import com.chelement.core.sysManagement.service.ChelementUserService; import com.chelement.core.utils.PermissionUtil; import com.chelement.core.web.common.ResultData; /** * * @author pat super */ public class CoreAccessControllerFilter extends HandlerInterceptorAdapter { @Autowired private ChannelUserService channelUserService; @Autowired CustomerService customerService; @Autowired ChelementUserService chelementUserService; @Autowired CommunityService communityService; @Autowired ChannelService channelService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("token"); if (StringUtils.isNotBlank(token)) { String result = PermissionUtil.exiteToken(token); if (result != null && result.equals("true")) { String type = token.substring(0, 1); BaseTokenDetailVO detailVO = PermissionUtil.getTokenDetailByToken(token); String accountId = detailVO.getAccountId(); switch (type) { case "1": ChannelUserTokenDetailVO channelUserTokenDetailVO = new ChannelUserTokenDetailVO(detailVO); ChannelUser channelUser = channelUserService.selectChannelUserWithCommunityIds(accountId); String channelId = channelUser.getChannelId(); channelUserTokenDetailVO.setChannelId(channelId); if (detailVO.getRoleName().equals(SysRoleEnum.经纪人.getValue())) { List<String> communityIds = channelUser.getCommunityIds(); channelUserTokenDetailVO.setCommunityIds(communityIds); } else if (detailVO.getRoleName().equals(SysRoleEnum.管理员.getValue()) || detailVO.getRoleName().equals(SysRoleEnum.会计师.getValue())) { Community queryCommunity = new Community(); queryCommunity.setChannelId(channelId); List<Community> communities = communityService.selectList(queryCommunity); List<String> communityIds = new ArrayList<String>(); for (Community community : communities) { communityIds.add(community.getId()); } channelUserTokenDetailVO.setCommunityIds(communityIds); } AccessControllerUtil.setChannelUserDetailFromThreadLocal(channelUserTokenDetailVO); break; case "2": CustomerTokenDetailVO customerTokenDetailVO = new CustomerTokenDetailVO(detailVO); AccessControllerUtil.setCustomerDetailFromThreadLocal(customerTokenDetailVO); break; case "3": ChelementUserTokenDetailVO chelementUserTokenDetailVO = new ChelementUserTokenDetailVO(detailVO); Channel query = new Channel(); query.setChelementUserId(accountId); List<Channel> channels = channelService.selectList(query); List<String> channelIds = new ArrayList<String>(); for (Channel channel : channels) { channelIds.add(channel.getId()); } chelementUserTokenDetailVO.setChannelIds(channelIds); AccessControllerUtil.setChelementUserDetailFromThreadLocal(chelementUserTokenDetailVO); break; default: throw new BizException("账户类型不存在!"); } return true; } ResultData data = getResultData(); response.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=UTF-8"); OutputStream out = response.getOutputStream(); PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, "utf-8")); // 返回json格式的提示 pw.println(JSON.toJSON(data)); pw.flush(); pw.close(); return false; } return false; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { AccessControllerUtil.removeChannelUserDetailFromThreadLocal(); } private ResultData getResultData() { ResultData data = new ResultData(); data.setSuccess(false); data.setDescription("Token 无效"); return data; } }
至于
InheritableThreadLocal
则是将可见扩张到子类:
package org.test; public class ThreadLocalTest { public static void main(String[] args) { User user = new User(new ThreadLocal<String>(), new InheritableThreadLocal<String>()); Book book = new Book(); Thread xx = new Thread(new SonUnsafeThread(new UnSafeRunnable(user, "pat1", book))); xx.start(); } } class Book { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } class User { private ThreadLocal<String> name; private InheritableThreadLocal<String> test; public User(ThreadLocal<String> name, InheritableThreadLocal<String> test) { this.name = name; this.test = test; } public String getName() { return name.get(); } public void setName(String names) { name.set(names); } public String getTest() { return test.get(); } public void setTest(String names) { test.set(names); } } class UnSafeRunnable implements Runnable { private User user; private String name; private Book book; public UnSafeRunnable(User user, String name, Book book) { this.user = user; this.name = name; this.book = book; user.setName(name); book.setName(name); user.setTest(name); } @Override public void run() { try { Thread.sleep(1000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } System.err.println(user.getTest() + "test"); } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Book getBook() { return book; } public void setBook(Book book) { this.book = book; } } /** * * @author patzheng 597439394@163.com * */ class SonUnsafeThread implements Runnable { private UnSafeRunnable thread; public SonUnsafeThread(UnSafeRunnable thread) { this.thread = thread; } @Override public void run() { System.err.println(thread.getUser()); System.err.println(thread.getUser().getName() + "ThreadLocal"); System.err.println(thread.getUser().getTest() + "sonThreadLocal"); } }
JAVA 线程基本知识汇总--ThreadLocal 和 InheritableThreadLoc
原文:http://my.oschina.net/payzheng/blog/513276