zoukankan      html  css  js  c++  java
  • ThreadLocal的认知与见解

    ThreadLocal:提高一个线程的局部变量,访问某个线程拥有自己局部变量(很难理解、看看下面这句话,顺便再讲个例子)。

      当使用ThreadLocal维护变量时,ThreadLocal为每一个使用该变量的线程提供独立的变量副本,所以每一个线程都有可以独立第改变自己副本的权力,而不会影响到其他线程所对应的副本。

    例子:创建三个线程、每个线程产生自己的序列号

    1、创建一个产生序列号的类

    /**
     * 定义线程序列号
     */
    class Res{
        private int count=0;
    
        public int getCount(){
            count = count +1;
            return  count;
        }
    }

    2、定义线程类

    /**
     * 定义线程类
     */
    class ThreadLocalTest extends Thread{
        private Res res;
        public ThreadLocalTest(Res res){
            this.res = res;
        }
        @Override
        public void run() {
            for (int i = 0; i < 3; i++) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(getName()+" : "+i+"------"+res.getCount());
            }
        }
    }

    3、为实现每个线程都能自己产生自己的序列号我们的主函数会这样写

     public static void main(String[] args) {
            Res res1 = new Res();
            Res res2 = new Res();
            Res res3 = new Res();
            
            ThreadLocalTest t1 = new ThreadLocalTest(res1);
            ThreadLocalTest t2 = new ThreadLocalTest(res2);
            ThreadLocalTest t3 = new ThreadLocalTest(res3);
    
            t1.start();
            t2.start();
            t3.start();
        }

    4、对应效果

    Thread-1 : 0------1
    Thread-0 : 0------1
    Thread-2 : 0------1
    Thread-2 : 1------2
    Thread-0 : 1------2
    Thread-1 : 1------2
    Thread-1 : 2------3
    Thread-0 : 2------3
    Thread-2 : 2------3

    注意:我们会看见对于线程Thread-0、Thread-1、Thread-2、会各自加到3(1—3)。但是我们这里创建了3个(麻烦)

       Res res1 = new Res();
            Res res2 = new Res();
            Res res3 = new Res();


    处理方法:使用ThreadLocal,就会在自己的空间自己开辟一个内存对于同一个变量。而且对于这个变量互相不影响

    1、将产生序列号的类改变

    /**
     * 定义线程序列号
     */
    class Res{
        //private int count=0;
        /**
         * 设置本地局部变量,和其他局部变量分隔开,互不影响
         */
        private ThreadLocal<Integer> count = new ThreadLocal<Integer>(){
            //设置当前局部变量,初始化值
            @Override
            protected Integer initialValue() {
                return 0;
            }
        };
    
        /*public int getCount(){
            count = count +1;
            return  count;
        }*/
        public int getCount(){
            int count = this.count.get() + 1; //注意着从新定义了count,别忘了this
            this.count.set(count);
            return  count;
        }
    }

    2、同时注意、注意啦,main函数

     public static void main(String[] args) {
            Res res = new Res();
    
            ThreadLocalTest t1 = new ThreadLocalTest(res);
            ThreadLocalTest t2 = new ThreadLocalTest(res);
            ThreadLocalTest t3 = new ThreadLocalTest(res);
    
            t1.start();
            t2.start();
            t3.start();
        }

    3、对应结果

    Thread-0 : 0------1
    Thread-2 : 0------1
    Thread-1 : 0------1
    Thread-1 : 1------2
    Thread-0 : 1------2
    Thread-2 : 1------2
    Thread-2 : 2------3
    Thread-0 : 2------3
    Thread-1 : 2------3
  • 相关阅读:
    BZOJ 3261 最大异或和(可持久化Trie)
    模板 普通平衡树
    HDU4825 Xor Sum(贪心+Trie树)
    二维LIS(CDQ分治)
    IOIOI卡片占卜(Atcoder-IOIOI カード占い)(最短路)
    USACO 2009 Dec cow toll paths 过路费-floyd
    [USACO08JAN]电话线Telephone Lines(分层图)/洛谷P1948
    lightoj 1038 Race to 1 Again 期望
    lightoj 1030 Discovering Gold 期望
    lightoj 1027 A Dangerous Maze 期望
  • 原文地址:https://www.cnblogs.com/karrya/p/10970987.html
Copyright © 2011-2022 走看看