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]

最新文章

  1. 如何利用 JConsole观察分析Java程序的运行,进行排错调优
  2. [转]ASP.NET中使用UpdatePanel实现局部异步刷新方法和攻略
  3. Oracle在dos命令下导出导入
  4. hdu----(4301)Divide Chocolate(状态打表)
  5. label 行距
  6. Python 读写excel数据
  7. hdu 1531(差分约束)
  8. 【转载】C#.Net 创建网页快捷方式
  9. bzoj2797
  10. TreeMap 红黑树实现
  11. 设计模式之(三)Proxy模式
  12. 26.单片机中利用定时器中断,在主流程while(1){}中设置每隔精确时间计量
  13. CodeForces - 27E--Number With The Given Amount Of Divisors(反素数)
  14. html学习 - 自己主动跳转与自己主动刷新
  15. Ajax交互,浏览器接收不到服务器的Json数据(跨域问题)
  16. 怎样查看当前QQ的版本号是多少
  17. Python学习笔记(Ⅰ)——Python程序结构与基础语法
  18. Linux安装python3.6
  19. Java技能提升之路
  20. 转:【专题二】HTTP协议详解

热门文章

  1. vue 单文件组件
  2. NumberUtils
  3. 【Unity】Unity中资源动态载入的两种方式之AssetsBundle
  4. 后台运行 screen命令
  5. 自己编写Android Studio插件 别停留在用的程度了(转载)
  6. Tomcat服务器的默认端口是多少?怎样修改tomcat的端口?
  7. 【BZOJ】3396: [Usaco2009 Jan]Total flow 水流 (最大流)
  8. cinder服务端的keystone认证机制
  9. VS2013远程调试IIS中的网站
  10. 12 个免费在线的 Web 网站性能测试工具