zoukankan      html  css  js  c++  java
  • 6.ThreadLocal类及应用技巧

      1 import java.util.Random;
      2 
      3 /**
      4  * ThreadLocal类及应用技巧
      5  * *******************************************************************
      6  * 每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map中增加一条记录,key
      7  * 分别是各自的线程,values是各自的set方法穿进去的值。在线程结束时可以调用ThreadLocal.clear();
      8  * 方法,这样会更快释放内存,不调用也可以,因为线程结束后也可以自动释放相关的ThreadLocal变量。
      9  * 实现对ThreadLocal变量的封装,让外界不要直接操作ThreadLocal变量
     10  *         对基本类型的数据的封装,这种应用相对少见。
     11  *         对对象类型的数据的封装,比较常见,即让某个类针对不同线程分别创建一个独立的实例对象。
     12  * 总结:
     13  *         一个ThreadLocal代表一个变量,故其中里只能放一个数据,你有两个变量都要线程范围内
     14  * 共享,则要定义两个ThreadLocal对象。如果有一百个变量要线程共享呢?把ThreadLocal封装
     15  * 到一个单例类中。
     16  * 
     17  * Struts2中的思想就是ThreadLocal模式
     18  * 
     19  * *******************************************************************
     20  * 虚拟机挂掉的时候注册钩子通知
     21  * Runtime->addShutdownHook(Thread hook) 
     22  * @author LiTaiQing
     23  */
     24 public class ThreadLocalTest {
     25     private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>();
     26     //private static ThreadLocal<MyThreadScopeData> myThreadScopeData = new ThreadLocal<MyThreadScopeData>();
     27     public static void main(String[] args){
     28         for(int i = 0; i < 2 ; i++){
     29             new Thread(new Runnable(){
     30                 @Override
     31                 public void run() {
     32                     int data = new Random().nextInt();
     33                     System.out.println(Thread.currentThread().getName() + " get put data :" + data);
     34                     threadLocal.set(data);
     35                     //myThreadScopeData.set(new MyThreadScopeData("name"+data,data));
     36                     MyThreadScopeData.getThreadInstance().setName("name" + data);
     37                     MyThreadScopeData.getThreadInstance().setAge(data);
     38                     new A().get();
     39                     new B().get();
     40                 }
     41             }).start();
     42         }
     43     }
     44     static class A{
     45         public void get(){
     46             int data = threadLocal.get();
     47             System.out.println("A from" + Thread.currentThread().getName() + " get put data :" + data);
     48             //MyThreadScopeData myData = myThreadScopeData.get();
     49             MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
     50             System.out.println("A from" + Thread.currentThread().getName() + " getMyData :" + myData.getName()+","+myData.getAge());
     51         }
     52     }
     53     static class B{
     54         public void get(){
     55             int data = threadLocal.get();
     56             System.out.println("B from" + Thread.currentThread().getName() + " get put data :" + data);
     57             //MyThreadScopeData myData = myThreadScopeData.get();
     58             MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
     59             System.out.println("B from" + Thread.currentThread().getName() + " getMyData :" + myData.getName()+","+myData.getAge());
     60         }
     61     }
     62 }
     63 class MyThreadScopeData{
     64     private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<MyThreadScopeData>();
     65     //private static MyThreadScopeData instance = null;//new MyThreadScopeData();
     66     
     67     private MyThreadScopeData(){};
     68     /**
     69      * 这里可以不用synchronized,因为位于不同的线程内分别保存在ThreadLocal中
     70      * @return
     71      */
     72     public static /*synchronized*/ MyThreadScopeData getThreadInstance(){
     73         MyThreadScopeData instance = map.get();
     74         //这种方式容易出现多线程并发问题。所以最好采用饿汉模式
     75         if(instance==null){
     76             instance = new MyThreadScopeData();
     77             map.set(instance);
     78         }
     79         return instance;
     80     }
     81     
     82     private String name;
     83     private int age;
     84     
     85 //    public MyThreadScopeData(String name, int age) {
     86 //        super();
     87 //        this.name = name;
     88 //        this.age = age;
     89 //    }
     90     public String getName() {
     91         return name;
     92     }
     93     public void setName(String name) {
     94         this.name = name;
     95     }
     96     public int getAge() {
     97         return age;
     98     }
     99     public void setAge(int age) {
    100         this.age = age;
    101     }
    102 }
  • 相关阅读:
    【zz】编程修养(一二三)
    Lec1计算字符串的相似度
    ASP.NETFLV处理流代码
    获取指定文件夹下所有子目录及文件(树形)
    Flex及AS3的百条常用知识(转载)
    [AS3] 解决跨域问题
    Asp.Net 文件操作基类(读取,删除,批量拷贝,删除,写入,获取文件夹大小,文件属性,遍历目录)
    ASP.NET中的File类和Directory类的相关知识
    Asp.net 备份、还原Ms SQLServer及压缩Access数据库
    http://blog.csdn.net/octverve/archive/2008/01/29/2071356.aspx
  • 原文地址:https://www.cnblogs.com/litaiqing/p/4635200.html
Copyright © 2011-2022 走看看