zoukankan      html  css  js  c++  java
  • Java中ThreadLocal模拟和解释

    一、测试代码

    public class XY_ThreadData
    {
     private static Integer data = 0;
     private static Map<Thread, Integer> map = new HashMap<Thread, Integer>();
     private static ThreadLocal<Integer> local = new ThreadLocal<Integer>();

     public static void setData(Integer value)
     {
      data = value;
     }

     public static Integer getData()
     {
      System.out.println("ThreadName:" + Thread.currentThread() + " data value:" + data);
      return data;
     }

     public static void setMapData(Integer value)
     {
      map.put(Thread.currentThread(), value);
     }

     public static Integer getMapData()
     {
      Object obj = map.get(Thread.currentThread());
      System.out.println("ThreadName:" + Thread.currentThread() + "map value:" + obj);
      return Integer.parseInt(obj.toString());
     }

     public static void setThreadLocalData(Integer value)
     {
      local.set(value);
     }

     public static Integer getThreadLocalData()
     {
      Object obj = local.get();
      System.out.println("ThreadName:" + Thread.currentThread() + "threadlocal value:" + obj);
      return Integer.parseInt(obj.toString());
     }
    }

    public class XY_ThreadData_Test
    {
     public static void main(String[] args)
     {
      for (int i = 0; i < 10; i++)
      {
       new Thread(new Runnable() {
        public void run()
        {
         final int value = new Random().nextInt(); // 每个线程自己创建的变量   
         XY_ThreadData.setData(value);
         XY_ThreadData.getData();
        }
       }).start();
      }

     }
    }
    ThreadName:Thread[Thread-3,5,main] data value:1046062244
    ThreadName:Thread[Thread-6,5,main] data value:-879673875
    ThreadName:Thread[Thread-2,5,main] data value:-125397465
    ThreadName:Thread[Thread-4,5,main] data value:-1546413071
    ThreadName:Thread[Thread-0,5,main] data value:754770101
    ThreadName:Thread[Thread-8,5,main] data value:-1666786926
    ThreadName:Thread[Thread-5,5,main] data value:-1666786926
    ThreadName:Thread[Thread-9,5,main] data value:1046062244
    ThreadName:Thread[Thread-1,5,main] data value:269410746
    ThreadName:Thread[Thread-7,5,main] data value:269410746
    分析:可以看到以下两个线程中data的值时一样的,没有做到各个线程变量独一份
    ThreadName:Thread[Thread-8,5,main] data value:-1666786926
    ThreadName:Thread[Thread-5,5,main] data value:-1666786926


    public class XY_ThreadData_Test
    {
     public static void main(String[] args)
     {
      for (int i = 0; i < 10; i++)
      {
       new Thread(new Runnable() {
        public void run()
        {
         final int value = new Random().nextInt();   
         XY_ThreadData.setMapData(value);
         XY_ThreadData.getMapData();
        }
       }).start();
      }

     }
    }
    ThreadName:Thread[Thread-0,5,main]map value:-1138167111
    ThreadName:Thread[Thread-4,5,main]map value:-1545929782
    ThreadName:Thread[Thread-6,5,main]map value:-1612385717
    ThreadName:Thread[Thread-3,5,main]map value:-1390594683
    ThreadName:Thread[Thread-8,5,main]map value:518506934
    ThreadName:Thread[Thread-2,5,main]map value:1583239372
    ThreadName:Thread[Thread-5,5,main]map value:995578601
    ThreadName:Thread[Thread-1,5,main]map value:-916627474
    ThreadName:Thread[Thread-7,5,main]map value:-960206804
    ThreadName:Thread[Thread-9,5,main]map value:-1187504747
    分析:模拟线程变量独一份,无重复


    public class XY_ThreadData_Test
    {
     public static void main(String[] args)
     {
      for (int i = 0; i < 10; i++)
      {
       new Thread(new Runnable() {
        public void run()
        {
         final int value = new Random().nextInt();
         XY_ThreadData.setThreadLocalData(value);
         XY_ThreadData.getThreadLocalData();
        }
       }).start();
      }

     }
    }
    ThreadName:Thread[Thread-1,5,main]threadlocal value:935024745
    ThreadName:Thread[Thread-4,5,main]threadlocal value:1207176846
    ThreadName:Thread[Thread-7,5,main]threadlocal value:-1503260374
    ThreadName:Thread[Thread-9,5,main]threadlocal value:-1538563684
    ThreadName:Thread[Thread-6,5,main]threadlocal value:955259906
    ThreadName:Thread[Thread-8,5,main]threadlocal value:894428541
    ThreadName:Thread[Thread-3,5,main]threadlocal value:730986356
    ThreadName:Thread[Thread-2,5,main]threadlocal value:-540225655
    ThreadName:Thread[Thread-5,5,main]threadlocal value:-2003809947
    ThreadName:Thread[Thread-0,5,main]threadlocal value:1917431015
    分析:线程变量独一份,无重复

     

    二、ThreadLocal分析

    要点1
    ThreadLocal不是用来解决共享对象的多线程访问问题的,一般情况下通过ThreadLocal.set()到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。各个线程中访问的是不同的对象。

     

    要点2
    说ThreadLocal使得各线程能够保持各自独立的一个对象,并不是通过ThreadLocal.set()来实现的,而是通过每个线程中的new对象的操作来创建的对象,每个线程创建一个,不是什么对象的拷贝或副本。通ThreadLocal.set()将这个新创建的对象的引用保存到各线程的自己的一个map中,每个线程都有这样一个map,执行ThreadLocal.get()时,各线程从自己的map中取出放进去的对象,因此取出来的是各自自己线程中的对象,ThreadLocal实例是作为map的key来使用的。

     

    要点3
    如果ThreadLocal.set()进去的东西本来就是多个线程共享的同一个对象,那么多个线程的ThreadLocal.get()取得的还是这个共享对象本身,还是有并发访问问题。


    更多关于ThreadLocal信息请参看:http://www.iteye.com/topic/103804

  • 相关阅读:
    从零开始学架构(一):架构师成长路径(转)
    从零开始学架构:开篇-文章大纲(转)
    JAVA通信系列二:mina入门总结(转)
    JAVA通信系列三:Netty入门总结(转)
    JAVA通信系列一:Java Socket技术总结(转)
    大型网站架构系列:消息队列(二)(转)
    大型网站架构系列:分布式消息队列(一)(转)
    大型网站架构系列:缓存在分布式系统中的应用(三)(转)
    大型网站架构系列:缓存在分布式系统中的应用(二)(转)
    大型网站架构系列:负载均衡详解(3)(转)
  • 原文地址:https://www.cnblogs.com/bbsno1/p/3265250.html
Copyright © 2011-2022 走看看