zoukankan      html  css  js  c++  java
  • 线程封闭

    1.jdbc和servlet的例子

    jdbc和servlet中,之所以是线程安全的,就是因为每个变量都封装在单个线程中,不会存在变量共享的状态,也就是说,你这一次获取的数据不会被下一个请求访问到,所以通过把变量都封闭在线程中,来达到了线程安全的目的.所以在servlet中使用 缓存  session  或者定义  static 等共享变量的时候就要小心,因为这些是多个线程所共享的,所以需要保证线程安全问题.

    2.栈封闭

    局部变量都封闭在执行线程中,只要不发布局部变量,就没有线程安全问题.

    public class SafeClass {
        
        
        
        public int safeMethod(Collection<String> collection) {
            //i被封装在的栈中,具体参考<深入理解java虚拟机>
            //i因为被封装在栈中,不会被别的线程访问到,所以也就保证了线程安全
            int i = 0;
            i++;
            //sortedSet 同理,也被封闭在栈中,没有逸出,也不会被别的线程访问到
            SortedSet<String> sortedSet = new TreeSet<String>();
            sortedSet.addAll(collection);
            
            return i;
        }
        
    }

    3.ThreadLocal类

    ThreadLocal能使线程中的值和保存值的对象关联起来,比如

    package demo04;
    
    import java.util.concurrent.TimeUnit;
    
    public class ThreadLocalTest {
        public static void main(String[] args) {
            ThreadLocal<String> threadLocal = new ThreadLocal<String>();
            Thread t1 = new Thread(() -> {threadLocal.set("t1"); System.out.println(threadLocal.get());});
            Thread t2 = new Thread(() -> {threadLocal.set("t2"); System.out.println(threadLocal.get());});
            
            
            t1.start();
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            t2.start();
            
            //结果为:
            //t1
            //t2
        }
    }

    t1 和 t2 中线程用相同的ThreadLocal保存值,但是在通过 get() 方法获取值的时候,只会返回之前在该线程 set() 方法设置的值,不会返回别的线程的值,相当于一个独立的副本.

    用jdbc举例子,在一个线程中,我们需要调用很多方法,但是每个方法都传入不同的Connection会有线程安全问题,所以我们可以把 Connection 封装在ThreadLocal中,来为每个线程创建一个全局变量.

    通过ThreadLocal类,我们可以为每个线程创建属于自己的 Connection,代码如下:

    public class ConnectionHolderTest {
        //new ThreadLocal<T>(){}
        //大括号中 {} 的意思表示每次调用get方法都会执行 initialValue这个方法.
        private static ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>(){
            public Connection initialValue() {
                try {
                    return DriverManager.getConnection("");
                } catch (SQLException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        };
        
        public static Connection getConnection() {
            return connectionHolder.get();
        }
    }
  • 相关阅读:
    django 自定义用户身份验证
    登录验证算法
    Scrapy
    爬虫性能相关
    Beautifulsoup模块
    selenium模块
    Cookie&Session
    Django Admin 本质
    JavaScript自执行函数和jquery扩展方法
    JS作用域与词法分析
  • 原文地址:https://www.cnblogs.com/lishuaiqi/p/11795829.html
Copyright © 2011-2022 走看看