j2ee高并发时使用全局变量须要注意的问题

原文:https://blog.csdn.net/jston_learn/article/details/21617311java

开发中,全局变量的使用很频繁,但对于多线程的访问,使用全局变量须要注意的地方有不少,下面作了个大概的总结。安全

全局变量的使用场合:多线程

1:定义只读的全局变量时,必须加final修饰,防止被修改。哪怕是私有的,也得加final,防止被反射修改。并发

2:对于须要屡次读写的全局变量,必定要用ThreadLocal封装,避免多线程并发时变量被屡次赋值等不安全的一些现象。ide

ThreadLocal封装静态全局变量和私有全局变量的代码示例:性能

import java.util.ArrayList;
import java.util.List;

public class RollDice {
    //ThreadLocal封装静态变量
    public static ThreadLocal<List<Object>> threadRollList = new ThreadLocal<List<Object>>(){
        //这里加同步是由于ThreadRollList是静态全局变量,防止ThreadLocal自己被并发。
        @Override
        protected synchronized List<Object> initialValue() {
            return new ArrayList<Object>(0);
        }
    };
    //用此种方式定义全局变量,遭遇多线程并发时,会出现bug.
    public static List<Object> rollList = new ArrayList<Object>(0);
        //私有全局变量
    public ThreadLocal<List<Object>> priTreadRollList = new ThreadLocal<List<Object>>(){

        //由于是私有变量,ThreadLocal自己会被放进线程,因此不用担忧并发,所以也不须要synchronized。
        @Override
        protected List<Object> initialValue() {
            return new ArrayList<Object>(0);
        }

    };

    //调用方式
    public static void main(String[] args) {
        //ThreadLocal调用方式
        threadRollList.get().add(new Object());
        //普通定义调用方式
        rollList.add(new Object());
    }
}

这里再扩展一下解决并发问题的两种经常使用的方案并进行对比:优化

使用synchronized来修饰,此方法至关于单线程队列执行,须要等待,有损性能,好处是不会增长内存的额外开销。.net

使用ThreadLocal封装变量,至关于把变量丢进执行线程中去,每new一个新的线程,变量也会new一次(不必定每次都new,这个要看程序怎么写。),对性能没有影响,但会增长系统额外的内存开销,但其执行完毕就销毁的机制使得ThreadLocal变成比较优化的并发解决方案。线程

相关文章
相关标签/搜索