ThreadLocal 示例

ThreadLocal, 从字面意思上看是本地线程. 但实际上它是一个线程本地变量.它的功能就是为每一个使用该变量的线程都提供一个变量值的副本, 从而使得不会与其他线程的副本冲突. 与使用synchronized解决同步问题一样的作用, 区别是synchronized是通过使用加锁的方式来实现的,而ThreadLocal是通过其内部定义的一个Map来存放每一个线程的变量副本来实现的.

 

看下面的例子, 通过多个线程来设置Student的age属性:

package threadLocal;
 
public class Student {
 
    private int age;
    private String name;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student [age=" + age + ", name=" + name + "]";
    }
    
    
}

有同步问题的代码:

package threadLocal;
 
import java.util.Random;
 
public class ThreadDemo implements Runnable {
    private static Student stu = new Student();
 
    @Override
    public void run() {
        accessStudent();
    }
 
    private void accessStudent() {
        try {
            Random r = new Random();
            int age =r.nextInt(100);
            stu.setAge(age);
            System.out.println(Thread.currentThread().getName() + ":" + stu);
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName() + ":" + "after 3 second:" + stu);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String[] args) {
        ThreadDemo demo = new ThreadDemo();
        for(int i=0;i<10;i++) {
            Thread a = new Thread(demo, "a"+i);
            a.start();
        }
    }
 

}

 

结果:

a4:Student [age=66, name=null]
a0:Student [age=87, name=null]
a1:Student [age=66, name=null]
a2:Student [age=66, name=null]
a3:Student [age=63, name=null]
a5:Student [age=63, name=null]
a8:Student [age=73, name=null]
a9:Student [age=14, name=null]
a6:Student [age=6, name=null]
a7:Student [age=45, name=null]
a3:after 3 second:Student [age=45, name=null]
a1:after 3 second:Student [age=45, name=null]
a0:after 3 second:Student [age=45, name=null]
a4:after 3 second:Student [age=45, name=null]
a9:after 3 second:Student [age=45, name=null]
a8:after 3 second:Student [age=45, name=null]
a5:after 3 second:Student [age=45, name=null]
a7:after 3 second:Student [age=45, name=null]
a2:after 3 second:Student [age=45, name=null]
a6:after 3 second:Student [age=45, name=null]


使用synchronized解决:

package threadLocal;
 
import java.util.Random;
 
public class ThreadDemo implements Runnable {
    private static Student stu = new Student();
 
    @Override
    public void run() {
        accessStudent();
    }
 
    private synchronized void accessStudent() {
        try {
            Random r = new Random();
            int age =r.nextInt(100);
            stu.setAge(age);
            System.out.println(Thread.currentThread().getName() + ":" + stu);
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName() + ":" + "after 3 second:" + stu);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    public static void main(String[] args) {
        ThreadDemo demo = new ThreadDemo();
        for(int i=0;i<10;i++) {
            Thread a = new Thread(demo, "a"+i);
            a.start();
        }
    }
 

}

 

结果:

a0:Student [age=86, name=null]
a0:after 3 second:Student [age=86, name=null]
a5:Student [age=14, name=null]
a5:after 3 second:Student [age=14, name=null]
a4:Student [age=31, name=null]
a4:after 3 second:Student [age=31, name=null]
a8:Student [age=58, name=null]
a8:after 3 second:Student [age=58, name=null]
a9:Student [age=5, name=null]
a9:after 3 second:Student [age=5, name=null]
a6:Student [age=10, name=null]
a6:after 3 second:Student [age=10, name=null]
a7:Student [age=22, name=null]
a7:after 3 second:Student [age=22, name=null]
a2:Student [age=37, name=null]
a2:after 3 second:Student [age=37, name=null]
a3:Student [age=92, name=null]
a3:after 3 second:Student [age=92, name=null]
a1:Student [age=41, name=null]
a1:after 3 second:Student [age=41, name=null]


使用ThreadLocal解决:
package threadLocal;
 
import java.util.Random;
 
public class ThreadLocalDemo implements Runnable {
 
    private static ThreadLocal<Student> studentLocal = new ThreadLocal<Student>();
 
    @Override
    public void run() {
        accessStudent();
    }
 
    private void accessStudent() {
        Student s = getStudent();
        Random r = new Random();
        int age = r.nextInt(100);
        s.setAge(age);
 
        System.out.println(Thread.currentThread().getName() + ":" + s);
        try {
            Thread.sleep(3000);
            System.out.println(Thread.currentThread().getName() + ":" + "after 3 second:" + s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    private Student getStudent() {
        Student s = studentLocal.get();
        if (s == null) {
            s = new Student();
            studentLocal.set(s);
        }
        return s;
    }
    public static void main(String[] args) {
        ThreadLocalDemo demo = new ThreadLocalDemo();
        for(int i=0;i<10;i++) {
            Thread a = new Thread(demo, "a"+i);
            a.start();
        }
    }
 
}

结果:

a9:Student [age=72, name=null]
a3:Student [age=10, name=null]
a8:Student [age=24, name=null]
a7:Student [age=5, name=null]
a1:Student [age=65, name=null]
a2:Student [age=39, name=null]
a6:Student [age=5, name=null]
a5:Student [age=61, name=null]
a4:Student [age=47, name=null]
a0:Student [age=41, name=null]
a9:after 3 second:Student [age=72, name=null]
a8:after 3 second:Student [age=24, name=null]
a3:after 3 second:Student [age=10, name=null]
a7:after 3 second:Student [age=5, name=null]
a1:after 3 second:Student [age=65, name=null]
a2:after 3 second:Student [age=39, name=null]
a5:after 3 second:Student [age=61, name=null]
a6:after 3 second:Student [age=5, name=null]
a0:after 3 second:Student [age=41, name=null]
a4:after 3 second:Student [age=47, name=null]

posted @ 2013-10-16 11:48  jeevan Wong  阅读(252)  评论(0编辑  收藏  举报