ThreadLocal模式探索

来源:互联网 发布:淄博网络推广公司 编辑:程序博客网 时间:2024/06/06 10:07

一、首先,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

  

0 0