• ThreadLocal的使用场景:Web容器、Spring容器、日志打印


    一、对于HTTP事务的理解

    一次HTTP请求,就是一个事务。事务者,必须完整的执行其中的所有步骤,不能中断。

    二、HTTP事务的隔离

    每次HTTP请求对应一个HTTP事务,而每个请求都对应一个线程,线程之间相互隔离,没有共享数据,这就是ThreadLocal一个典型的应用场景。

    三、ThreadLocal在Web容器中的使用场景【针对HTTP事务】

    ThreadLocal充当Web容器中存储Session的载体。当请求到来时,将当前Session信息存储在ThreadLocal中,在请求处理过程中可以随时使用Session信息,每个请求之间的Session信息互不影响。当请求处理完成后通过remove方法将当前Session信息清除即可。

    四、ThreadLocal在Spring容器中的使用场景【针对JDBC事务】

    Spring框架在事务开始时会给当前线程绑定一个Jdbc Connection,在整个事务过程都是使用该线程绑定的Connection来执行数据库操作,实现了事务的隔离性。

    五、日志打印

    同一线程的日志一起打印,或者说一次事务的日志一起打印,因为一般默认一次事务都是由同一个线程执行的,将事务的日志保存在线程局部变量当中,当事务执行完成的时候统一打印。

    public class ErrorContext
    
    {
    
     
    
        private static final String LINE_SEPARATOR = System.getProperty("line.separator", "
    ");
    
        private static final ThreadLocal<ErrorContext> LOCAL = new ThreadLocal<ErrorContext>();
    
     
    
        private String message;
    
     
    
        private ErrorContext()
    
        {
    
        }
    
     
    
        public static ErrorContext instance()
    
        {
    
            ErrorContext context = LOCAL.get();
    
            if (context == null)
    
            {
    
                context = new ErrorContext();
    
                LOCAL.set(context);
    
            }
    
            return context;
    
        }
    
     
    
        public ErrorContext message(String message)
    
        {
    
            this.message = message;
    
            return this;
    
        }
    
     
    
        public ErrorContext reset()
    
        {
    
     
    
            message = null;
    
            LOCAL.remove();
    
            return this;
    
        }
    
     
    
        @Override
    
        public String toString()
    
        {
    
            StringBuilder description = new StringBuilder();
    
     
    
            if (this.message != null)
    
            {
    
                description.append("### ");
    
                description.append(this.message);
    
                description.append(LINE_SEPARATOR);
    
            }
    
     
    
            return description.toString();
    
        }
    
     
    
        public static void main(String[] args)
    
        {
    
     
    
            Runnable task1 = () -> {
    
     
    
                ErrorContext cxt = ErrorContext.instance();
    
                cxt.message("info");
    
     
    
                System.out.println(cxt);
    
                cxt.reset();
    
            };
    
     
    
            Runnable task2 = () -> {
    
                ErrorContext cxt = ErrorContext.instance();
    
                cxt.message("error");
    
                System.out.println(cxt);
    
                cxt.reset();
    
            };
    
     
    
            new Thread(task1).start();
    
     
    
            new Thread(task2).start();
    
     
    
        }
    
    }

    六、参考内容

    SpringMVC 中文官网:http://www.springmvc.cn/

  • 相关阅读:
    e.printStackTrace()打印在哪里以及如何e.printStackTrace()的内容打印在日志中
    oracle分组并在组内排序
    Java.util.Calendar类
    oracle分页查询
    两个map合并
    【自动化测试】无需图形界面环境下的浏览器开源项目
    【运维工具】logrotate 日志管理神器
    如何查看google chrome 插件源码
    phpexcel 读取数据
    常用开发资源收集
  • 原文地址:https://www.cnblogs.com/nanfeng99/p/11226157.html
Copyright © 2020-2023  润新知