zoukankan      html  css  js  c++  java
  • 《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();
            }
        }
    
    }

  • 相关阅读:
    firefox, chrome常见插件
    数据库左连接left join、右连接right join、内连接inner join on 及 where条件查询的区别
    Springmvc + mybatis + spring 配置,spring事物
    Android如何连接MySQL数据库
    Android MP3录音实现
    Android RecyclerView的基本使用
    Java输入流之BufferReader和Scanner的用法!
    Android 网络通信框架Volley简介
    your project contains error(s),please fix them before running your application.错误总结
    新建android项目报错,代码中找不到错误
  • 原文地址:https://www.cnblogs.com/Michael2397/p/7858117.html
Copyright © 2011-2022 走看看