• 《Java多线程编程核心技术》读后感(十二)


    类ThreadLocal的使用

    主要解决的是每个线程绑定自己的值,可以将ThreadLocal类比喻成全局存放数据的盒子,盒子中可以存储每个线程私有数据。

    类ThreadLocal解决的是变量在不同线程间的隔离线,也就是不同线程拥有自己的值,不同线程中的值是可以放入ThreadLocal类中进行保存的

    方法get()与null

    package Third;
    
    public class Run {
        public static ThreadLocal tl = new ThreadLocal();
    
        public static void main(String[] args) {
            if (tl.get() == null) {
                System.out.println("从未放过值");
                tl.set("我的值");
            }
            System.out.println(tl.get());
            System.out.println(tl.get());
        }
    
    }

    验证线程变量的隔离性

    package Third;
    
    public class ThreadA extends Thread {
    
        @Override
        public void run() {
            try {
                for (int i = 0; i < 100; i++) {
                    if (Tools.tl.get() == null) {
                        Tools.tl.set("ThreadA" + (i + 1));
                    } else {
                        System.out.println("ThreadA get Value=" + Tools.tl.get());
                    }
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    }
    package Third;
    
    public class ThreadB extends Thread {
    
        @Override
        public void run() {
            try {
                for (int i = 0; i < 100; i++) {
                    if (Tools.tl.get() == null) {
                        Tools.tl.set("ThreadB" + (i + 1));
                    } else {
                        System.out.println("ThreadB get Value=" + Tools.tl.get());
                    }
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    }
    package Third;
    
    public class Tools {
    
        public static ThreadLocal tl = new ThreadLocal();
    
    }
    package Third;
    
    public class Run {
    
        public static void main(String[] args) {
    
            try {
                ThreadA a = new ThreadA();
                ThreadB b = new ThreadB();
                a.start();
                b.start();
    
                for (int i = 0; i < 100; i++) {
                    if (Tools.tl.get() == null) {
                        Tools.tl.set("Main" + (i + 1));
                    } else {
                        System.out.println("Main get Value=" + Tools.tl.get());
                    }
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
    }

    每个线程取出自己的数据

    package Third;
    
    import java.util.Date;
    
    public class ThreadA extends Thread {
    
        @Override
        public void run() {
            try {
                for (int i = 0; i < 20; i++) {
                    if (Tools.tl.get() == null) {
                        Tools.tl.set(new Date());
                    }
                    System.out.println("A " + Tools.tl.get().getTime());
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }
    package Third;
    
    import java.util.Date;
    
    public class ThreadB extends Thread {
    
        @Override
        public void run() {
            try {
                for (int i = 0; i < 20; i++) {
                    if (Tools.tl.get() == null) {
                        Tools.tl.set(new Date());
                    }
                    System.out.println("B " + Tools.tl.get().getTime());
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }
    package Third;
    
    import java.util.Date;
    
    public class Tools {
    
        public static ThreadLocal<Date> tl = new ThreadLocal<Date>();
    
    }
    package Third;
    
    public class Run {
    
        public static void main(String[] args) {
            try {
                ThreadA a = new ThreadA();
                a.start();
    
                Thread.sleep(1000);
    
                ThreadB b = new ThreadB();
                b.start();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
        }
    
    }

    怎么实现第一次调用get()不返回null呢?也就是具有默认值的效果

    解决get()返回null问题

    package Third;
    
    public class ThreadLocalExt extends ThreadLocal {
        @Override
        protected Object initialValue() {
            return "我是默认值 第一次get不再为null";
        }
    }
    package Third;
    
    public class Run {
        public static ThreadLocalExt tl = new ThreadLocalExt();
    
        public static void main(String[] args) {
            if (tl.get() == null) {
                System.out.println("从未放过值");
                tl.set("我的值");
            }
            System.out.println(tl.get());
            System.out.println(tl.get());
        }
    
    }

    此案例仅仅证明main线程有自己的值,那其他线程呢?

    再次验证线程变量的隔离性

    package Third;
    
    public class Tools {
        public static ThreadLocalExt tl = new ThreadLocalExt();
    }
    package Third;
    
    import java.util.Date;
    
    public class ThreadLocalExt extends ThreadLocal {
        @Override
        protected Object initialValue() {
            return new Date().getTime();
        }
    }
    package Third;
    
    public class ThreadA extends Thread {
    
        @Override
        public void run() {
            try {
                for (int i = 0; i < 10; i++) {
                    System.out.println("在ThreadA线程中取值=" + Tools.tl.get());
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }
    package Third;
    
    public class Run {
    
        public static void main(String[] args) {
            try {
                for (int i = 0; i < 10; i++) {
                    System.out.println("       在Main线程中取值=" + Tools.tl.get());
                    Thread.sleep(100);
                }
                Thread.sleep(5000);
                ThreadA a = new ThreadA();
                a.start();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
    }

  • 相关阅读:
    BZOJ3073 Journeys
    UOJ261 【NOIP2016】天天爱跑步 LCA+动态开点线段树
    [bzoj2654] tree 最小生成树kruskal+二分
    【ZJOI2007】【BZOJ1059】矩阵游戏 匈牙利算法
    [Bzoj 2427] [HAOI2010] 软件安装 tarjan缩点+树形DP
    [CQOI2011]放棋子--DP
    BZOJ 3990 排序
    (六)接入层:反向代理,接入层扩容,负载均衡
    (五)伪分布式:你以为,多机就是分布式?
    (四)容量设计:流量高低,对架构究竟有什么影响?
  • 原文地址:https://www.cnblogs.com/Michael2397/p/7858117.html
Copyright © 2020-2023  润新知