JAVA 线程基本知识汇总--ThreadLocal 和 InheritableThreadLoc

Wesley13
• 阅读 638
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");
    }
}
点赞
收藏
评论区
推荐文章
待兔 待兔
2个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
2年前
java8 List集合的排序,求和,取最大值,按照条件过滤
public class Java8Test{public static void main(Stringargs){Personp1 new Person("麻子", 31);Personp2 new Person("
Wesley13 Wesley13
2年前
java8之lambda表达式(变量作用域)
通常,我们希望能够在lambda表达式的闭合方法或类中访问其他的变量,例如:package java8test;public class T1 {    public static void main(String args) {        repeatMessage("Hello", 20);
Wesley13 Wesley13
2年前
java递归算法+遍历磁盘文件
package com.cnse.io.ioDemo;import java.io.File;//java遍历磁盘下所有的文件 递归 recursionpublic class FlList {    public static void main(String args) {
Wesley13 Wesley13
2年前
java字符串比较和jdkequals源码分析
 package com.cnse.demo;/  比较两个字符串相等 /public class StringTest { public static void main(String args) {  int checkLength  0;  String str
Stella981 Stella981
2年前
Google Guava Striped 实现细粒度锁
首先不谈Striped能做什么,我们来看下如下的代码/   购买产品   @param user 用户   @param buyAmount 购买金额   @param productId 产品编号  / public static void buy(String user
Stella981 Stella981
2年前
BlockingQueue队列的使用
import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;public class BlockingQueueTest { public static void main(String args) 
Stella981 Stella981
2年前
Json转化
importjava.util.\;importnet.sf.json.JSONArray;importnet.sf.json.JSONObject;publicclassTest {public static void main(String\\ args) {//对象转jsonStu s  new Stu(
Wesley13 Wesley13
2年前
5.48 正则表达式的概述和基本使用
import java.util.Scanner;public class RegexDemo {public static void main(String args) {// 创建键盘录入对象Scanner sc  new Scanner(System.in);Sys
Stella981 Stella981
2年前
CountDownLatch 计数栓
import java.util.concurrent.CountDownLatch;/  Created by zyBourn on 15/12/25. /public class Entity {    public static void main(String args)