• 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 . "
    ";
        
        function fn1() {
            $b = "hello, b!";
            echo "global a is:" . $a . "
    ";
        }
        
        fn1();

    需要加上 global关键词才行,php这么做的目的在于其没有规定的入口函数,不使用全局变量从而避免变量污染:

    <?php
    
    $a = "hello, a!";
    echo $a . "
    ";
    
    function fn1() {
        global $a;
        $b = "hello, b!";
        echo "global a is:" . $a . "
    ";
    }
    
    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 对于一般的开发工作,用处不一定很多,但是对于框架一类操作就比较有用了。

  • 相关阅读:
    DHCP分配ip地址。0.0.0.0与255.255.255.255
    net-snmp配置文件详解
    net-snmp开发中出现“Error opening specified endpoint"" ”的解决方案
    Elasticsearch 学习笔记
    Prometheus 监控报警系统 AlertManager 之邮件告警
    Match All Query
    Elasticsearch postman
    Centos7修改root密码
    ElasticSearch中profile API的使用
    kafka查询某时间段内的消息
  • 原文地址:https://www.cnblogs.com/yougewe/p/8997677.html
Copyright © 2020-2023  润新知