<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    I want to fly higher
    programming Explorer
    posts - 114,comments - 263,trackbacks - 0
    1.代碼示例
    package com.landon.mavs.example.concurrent;

    import java.util.concurrent.ThreadLocalRandom;

    /**
     * 
     * ThreadLocal例子
     * 
     * <pre>
     *     1.線程局部變量.其完全不提供鎖.以空間換時間的手段,為每個線程提供變量的獨立副本,以保證線程的安全.
     *     2.接口:
     *         public T get() 返回此線程局部變量的當前線程副本中的值
     *         public void set(T value) 將此線程局部變量的當前線程副本中的值設置為指定值
     *         public void remove() 移除此線程局部變量當前線程的值
     *         protected T initialValue() 返回此線程局部變量的當前線程的“初始值”
     *  3.源碼:
     *       // 1.取得當前調用線程t 2.根據t獲得ThreadLocalMap【Entry(ThreadLocal k, Object v)】(即每個線程都有一個threadLocals)
     *       // 3. 如果map為不null,則將this和value設置到map;否則創建map
     *       public void set(T value) {
     *         Thread t = Thread.currentThread();
     *         ThreadLocalMap map = getMap(t);
     *         if (map != null)
     *             map.set(this, value);
     *         else
     *             createMap(t, value);
     *     }
     *     
     *     // 1.取得當前調用線程t 2.取得t線程關聯的ThreadLocalMap
     *     // 3.如果map不為null則將this作為key得到Entry.然后得到值.
     *     // 4.如果map為null則返回initialValue(默認為null,同時會將initialValue set至當前線程)
     *     public T get() {
     *         Thread t = Thread.currentThread();
     *         ThreadLocalMap map = getMap(t);
     *         if (map != null) {
     *             ThreadLocalMap.Entry e = map.getEntry(this);
     *             if (e != null)
     *                 return (T)e.value;
     *         }
     *         return setInitialValue();
     *     }.
     *  4.注意:
     *      1.不同線程間的對象副本并不是由ThreadLocal創建的.因為set方法未生成任何value的副本.所以將一個對象的實例設置到不同線程的ThreadLocal中,同樣無法保證線程安全.
     *  所以需要每個線程內創建副本,然后設置到ThreadLocal中(即ThreadLocal只是一個key而已.).
     *      2.從get方法的最后一句看出,如果沒有set,則第一次調用get方法時會調用initialValue;可使用匿名內部類覆寫此方法,如果不希望初始值為null.另外如果調用了remove方法,即從
     *  ThreadLocalMap移除ThreadLocal key,則再次調用get方法時依然會調用initialValue.
     *      3.ThreadLocal實例通常是類中的 private static final字段(1.其只是用來做key,和當前線程綁定,所以用static方便 2.通常用靜態方法直接獲取局部變量實例,
     *  如ThreadLocalRandom),它們希望將狀態與某一個線程相關聯.
     *  
     *  5.總結:
     *      簡單來說,ThreadLocal就是一個當前線程局部變量表的一個key,該key對應的V是new出來的一個新值,每個線程的都不一樣.這樣
     *  當前線程拿到ThreadLocal.get->則直接獲得線程當前局部變量表對應的V.(第一次調用get時會將會將initialValue set,
     *  所以初始化ThreadLocal的時候可覆寫initialValue).
     * </pre>
     * 
     * @author landon
     * 
     
    */

    public class ThreadLocalExample {
        
    // 一個線程局部變量
        private static final ThreadLocal<ThreadLocalVar> localVar = new ThreadLocal<>();

        
    // 線程局部變量內部的V
        private static class ThreadLocalVar {
            
    public int var;
        }


        
    // 初始化的時候指定了localVar2的變量值
        private static final ThreadLocal<ThreadLocalVar> localVar2 = new ThreadLocal<ThreadLocalVar>() {
            
    protected ThreadLocalVar initialValue() {
                
    return new ThreadLocalVar();
            }

        }
    ;

        
    // 一個任務
        private static class ThreadLocalTask implements Runnable {
            @Override
            
    public void run() {
                
    // 注意這里必須要new一個值,然后set.->即set了當前調用線程中局部變量的值.
                ThreadLocalVar var = new ThreadLocalVar();
                localVar.set(var);

                
    // 隨機一個局部變量的值.這里用到了ThreadLocalRandom,一個活生生的例子

                
    // public static ThreadLocalRandom current() {
                
    // return localRandom.get();
                
    // }

                
    // 這里初始化了一個線程局部變量值,是new了一個ThreadLocalRandom.這個很關鍵.
                
    // private static final ThreadLocal<ThreadLocalRandom> localRandom =
                
    // new ThreadLocal<ThreadLocalRandom>() {
                
    // protected ThreadLocalRandom initialValue() {
                
    // return new ThreadLocalRandom();
                
    // }
                
    // };
                var.var = ThreadLocalRandom.current().nextInt();

                
    // 打印當前調用線程,即當前調用線程的線程局部變量的值.
                System.out.println("curThread:" + Thread.currentThread().getName()
                        
    + " localVar:" + localVar.get().var);

                
    // 操作localVar2,將當前線程的id復制給localvar2
                localVar2.get().var = (int) Thread.currentThread().getId();

                System.out.println("curThread:" + Thread.currentThread().getName()
                        
    + " localVar2:" + localVar2.get().var);
            }

        }


        
    // 從輸出看,ThreadLocalExample#localVar如果不是線程局部變量則多線程操作時,一定要加鎖的.但是如果是線程局部變量,則其只用來做一個key而已,局部變量的值是new出來
        
    // 并設置,所以每個線程的ThreadLocal的get值都是互相沒有任何關系的。
        
    // 多線程之間可隨意操作localVar.
        
    // 同理localvar2
        public static void main(String[] args) {
            
    for (int i = 0; i < 5; i++{
                
    new Thread(new ThreadLocalTask(), "Thread-" + i).start();
            }


            
    // 主線程操作
            localVar.set(new ThreadLocalVar());
            localVar.get().var = 100;

            System.out.println("curThread:" + Thread.currentThread().getName()
                    
    + " localVar:" + localVar.get().var);

            
    // 主線程操作localvar2
            localVar2.get().var = 201;

            System.out.println(
    "curThread:" + Thread.currentThread().getName()
                    
    + " localVar:" + localVar2.get().var);
        }

    }



    2.本篇主要介紹了ThreadLocal的用法,作為解決線程安全的一種方法.ThreadLocalRandom就是一個典型例子.

    posted on 2014-03-05 15:17 landon 閱讀(1831) 評論(0)  編輯  收藏 所屬分類: Program
    主站蜘蛛池模板: 99久久99久久精品免费观看| 亚洲色大成网站www永久男同| 亚洲中文字幕无码久久2017| 亚洲av无码成人黄网站在线观看| 精品日韩亚洲AV无码| 亚洲第一成年网站视频| 国产做国产爱免费视频| 在线看片v免费观看视频777| 国产又粗又猛又爽又黄的免费视频 | 在线观看永久免费视频网站| 亚洲啪啪AV无码片| 国产 亚洲 中文在线 字幕| 黄色视频在线免费观看| 最近高清国语中文在线观看免费| 中文字幕人成人乱码亚洲电影 | 又黄又大又爽免费视频| 亚洲欧洲日本精品| 精品乱子伦一区二区三区高清免费播放| 亚洲国产成人爱av在线播放| 亚洲va成无码人在线观看| 热久久这里是精品6免费观看| 亚洲va中文字幕无码久久| 亚洲国产精品免费在线观看| 男女做羞羞的事视频免费观看无遮挡| 在线观看亚洲成人| 热re99久久6国产精品免费| 亚洲人成免费电影| 久久免费观看国产精品88av| 亚洲毛片av日韩av无码| 亚洲hairy多毛pics大全| 亚洲精品老司机在线观看| 免费污视频在线观看| 中文字幕中韩乱码亚洲大片| 美女被艹免费视频| 日韩精品视频免费观看| 你是我的城池营垒免费看| 亚洲深深色噜噜狠狠网站| 亚洲综合在线另类色区奇米| 免费H网站在线观看的| 久久国产乱子伦精品免费午夜| 亚洲精品mv在线观看 |