java中的全局變量如何實現?ThreadLocal~


  全局變量就是不管你在哪里,都能夠直接引用的變量,還不用擔心各種問題。每個語言都有自己的全局變量,我想!

  一般地,面向過程的語言當中,可能就是一個聲明在最前面的變量,后面的代碼直接引用,就成了全局變量!(最經典的C就是這樣的)

如:js 中:

var a = "hello,a!";

alert(a);

function fn1() {
    var b = "hello, b!"
    alert("global var a: " + a);
}

fn1();

 但是也有的語言是不允許直接引用的,如PHP:(以下代碼是會報錯的,因為php中不允許函數中直接引用全局變量)

<?php 
    $a = "hello, a!";
    echo $a . "\n";
    
    function fn1() {
        $b = "hello, b!";
        echo "global a is:" . $a . "\n";
    }
    
    fn1();

需要加上 global關鍵詞才行,php這么做的目的在於其沒有規定的入口函數,不使用全局變量從而避免變量污染:

<?php

$a = "hello, a!";
echo $a . "\n";

function fn1() {
    global $a;
    $b = "hello, b!";
    echo "global a is:" . $a . "\n";
}

fn1();

 但是要在java中實現全局變量,可就沒這么簡單了。不是因為訪問一個全局變量有問題,而是訪問全局可變變量時,往往會引發線程安全問題,那么就不能夠隨便用全局變量了。

public class Constants {
    public static String CONST_6 = "6";
}

在需要使用的地方,直接使用 Constants.CONST_6 = 7; 就行了。但是因為java天生就是多線程環境,假如再來一個線程也更改這個變量,那么就出問題了。同等情況下,其他語言則往往是多進程環境,不必考慮變量的線程安全問題。

當然了,java自然是考慮到有需要訪問全局變量的需求的,所以有了,ThreadLocal,這個類就是保證了線程安全的,可以作為全局變量使用的。

public class GlobalVarManager {
    private static ThreadLocal<GlobalVars> globalVars = new ThreadLocal<>();

    public static GlobalVars getGlobalVars() {
        return globalVars.get();
    }

    public static void setGlobalVars(GlobalVars conn) {
        globalVars.set(conn);
    }
}

如上方法,在外面使用 set, get 方式,就可以做到全局變量共享了,還保證了線程安全。

ThreadLocal的操作有三個set,get,remove,其實現原理為,使用一個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);
    }
    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
     public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }

ThreadLocal 對於一般的開發工作,用處不一定很多,但是對於框架一類操作就比較有用了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM