• ThreadLocal模式探索


    一、首先,ThreadLocal模式使共享数据能多个线程被访问,每个线程访问的只是这个数据的副本,线程之间互不影响。

      例子1:

    package Thread2;
    
    public class Counter {
    
        //新建一个静态的ThreadLocal变量,并通过get方法将其变为一个可访问的对象
        private static ThreadLocal<Integer> counterContext = new ThreadLocal<Integer>(){
            protected synchronized Integer initialValue(){
                return 10;
            }
        };
        
        //通过静态的get方法访问ThreadLocal中存储的值
        public static Integer get(){
            return counterContext.get();
        }
        
        //通过静态的set方法将变量值设置到ThreadLocal中
        public static void set (Integer value){
            counterContext.set(value);
        }
        //封装业务逻辑,操作存储于ThreadLocal中的变量
        public static Integer getNextCounter(){
            counterContext.set(counterContext.get()+1);
            return counterContext.get();
        }
    }
    package Thread2;
    
    public class ThreadLocalTest extends Thread {
    
        public void run(){
            
            for(int i = 0; i < 3; i ++){
                System.out.println("Thread[" + Thread.currentThread().getName() + " ], "
                        + "counter = " + Counter.getNextCounter());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        
    }
    package Thread2;
    
    public class Test2 {
    
        public static void main(String[] args) throws Exception{
            
            ThreadLocalTest testThread1 = new ThreadLocalTest();
            ThreadLocalTest testThread2 = new ThreadLocalTest();
            ThreadLocalTest testThread3 = new ThreadLocalTest();
            
            testThread1.start();
            testThread2.start();
            testThread3.start();
        }
    }

    运行结果:

    Thread[Thread-2 ], counter = 11
    Thread[Thread-0 ], counter = 11
    Thread[Thread-1 ], counter = 11
    Thread[Thread-1 ], counter = 12
    Thread[Thread-2 ], counter = 12
    Thread[Thread-0 ], counter = 12
    Thread[Thread-2 ], counter = 13
    Thread[Thread-1 ], counter = 13
    Thread[Thread-0 ], counter = 13

    例子2:

    package Thread;
    
    class AStub {
        public void output() {
            LocalThreadScopeData data = LocalThreadScopeData.getInstance();
            if (data != null)
                System.out.println("AStub:" + Thread.currentThread().getName()
                        + ": data name = " + data.getName() + "age= "
                        + data.getAge());
        }
    }
    
    package Thread;
    
    class BStub {
        public void output() {
            LocalThreadScopeData data = LocalThreadScopeData.getInstance();
            if (data != null)
                System.out.println("BStub:" + Thread.currentThread().getName()
                        + ": data name = " + data.getName() + "age= "
                        + data.getAge());
        }
    }
    
    
    
    package Thread;
    
    class LocalThreadScopeData {
        // 把对象与当前线程绑定
        private static ThreadLocal<LocalThreadScopeData> mThreadLocal = new ThreadLocal<LocalThreadScopeData>();
        // 当前实例
        private static LocalThreadScopeData instance = null;
    
        // 单例模式
        public static LocalThreadScopeData getInstance() {
            instance = mThreadLocal.get();
            if (instance == null) {
                instance = new LocalThreadScopeData();
                mThreadLocal.set(instance);
            }
            return instance;
        }
    
        private String name;// 姓名
        private Integer age;// 年龄
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    
    
    package Thread;
    import java.util.Random;
    
    public class ThreadTest {
    
        public static void main(String argv[]) {
    
            // 启动俩个线程
            for (int i = 0; i < 2; i++) {
    
                new Thread() {
                    
                    public void run() {
                        int value = new Random().nextInt(10);
                        LocalThreadScopeData data = LocalThreadScopeData
                                .getInstance();
                        data.setAge(value);
                        data.setName("name" + value);
                        System.out.println("main:" + Thread.currentThread().getName()
                                + "name = name " + value);
                        
                        try {
                        Thread.sleep(1000);
                        } catch (InterruptedException e) {
                        }
                        new AStub().output();
                        new BStub().output();
                    }
                }.start();
            }
        }
    }

    运行结果:

    main:Thread-0name = name 5
    main:Thread-1name = name 0
    AStub:Thread-0: data name = nullage= null
    AStub:Thread-1: data name = name0age= 5
    BStub:Thread-0: data name = nullage= null
    BStub:Thread-1: data name = name0age= 5

    例子3:

    package Thread4;
    
    public class Student {
        private int age = 0;   //年龄
     
        public int getAge() {
            return this.age;
        }
     
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    package Thread4;
    
    import java.util.Random;
    
    public class ThreadLocalDemo implements Runnable {
        //创建线程局部变量studentLocal,在后面你会发现用来保存Student对象
        private final static ThreadLocal studentLocal = new ThreadLocal();
     
        public static void main(String[] agrs) {
            ThreadLocalDemo td = new ThreadLocalDemo();
            Thread t1 = new Thread(td, "a");
            Thread t2 = new Thread(td, "b");
            t1.start();
            t2.start();
        }
     
        public void run() {
            accessStudent();
        }
     
        /**
         * 示例业务方法,用来测试
         */
        public void accessStudent() {
            //获取当前线程的名字
            String currentThreadName = Thread.currentThread().getName();
            System.out.println(currentThreadName + " is running!");
            //产生一个随机数并打印
            Random random = new Random();
            int age = random.nextInt(100);
            System.out.println("thread " + currentThreadName + " set age to:" + age);
            //获取一个Student对象,并将随机数年龄插入到对象属性中
            Student student = getStudent();
            student.setAge(age);
            System.out.println("thread " + currentThreadName + " first read age is:" + student.getAge());
            try {
                Thread.sleep(500);
            }
            catch (InterruptedException ex) {
                ex.printStackTrace();
            }
            System.out.println("thread " + currentThreadName + " second read age is:" + student.getAge());
        }
     
        protected Student getStudent() {
            //获取本地线程变量并强制转换为Student类型
            Student student = (Student) studentLocal.get();
            //线程首次执行此方法的时候,studentLocal.get()肯定为null
            if (student == null) {
                //创建一个Student对象,并保存到本地线程变量studentLocal中
                student = new Student();
                studentLocal.set(student);
            }
            return student;
        }
    }

    运行结果:

    b is running!
    thread b set age to:31
    a is running!
    thread a set age to:45
    thread b first read age is:31
    thread a first read age is:45
    thread b second read age is:31
    thread a second read age is:45

    参考:struts2设计模式,

    http://lavasoft.blog.51cto.com/62575/51926/

    http://blog.csdn.net/com360/article/details/6789367

      

  • 相关阅读:
    iOS自动布局框架-Masonry详解
    iOS设置圆角的三种方式
    iOS9 App Thinning(应用瘦身)功能介绍
    以无线方式安装企业内部应用
    Xcode 9 Analyzing Crash Reports
    IQKeyboardManager 问题锦集
    列表
    字符串索引,切片,步长及方法详解
    while循环语句、格式化输出、常用运算符、字符编码
    if语句简单练习
  • 原文地址:https://www.cnblogs.com/mynona/p/3393223.html
Copyright © 2020-2023  润新知