java高并发时使用全局变量问题

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

全局变量的使用场合:

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

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


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


  
  
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. public class RollDice {
  4. //ThreadLocal封装静态变量
  5. public static ThreadLocal<List<Object>> threadRollList = new ThreadLocal<List<Object>>(){
  6. //这里加同步是因为ThreadRollList是静态全局变量,防止ThreadLocal本身被并发。
  7. @Override
  8. protected synchronized List<Object> initialValue() {
  9. return new ArrayList<Object>( 0);
  10. }
  11. };
  12. //用此种方式定义全局变量,遭遇多线程并发时,会出现bug.
  13. public static List<Object> rollList = new ArrayList<Object>( 0);
  14. //私有全局变量
  15. public ThreadLocal<List<Object>> priTreadRollList = new ThreadLocal<List<Object>>(){
  16. //因为是私有变量,ThreadLocal本身会被放进线程,所以不用担心并发,因此也不需要synchronized。
  17. @Override
  18. protected List<Object> initialValue() {
  19. return new ArrayList<Object>( 0);
  20. }
  21. };
  22. //调用方式
  23. public static void main(String[] args) {
  24. //ThreadLocal调用方式
  25. threadRollList.get().add( new Object());
  26. //普通定义调用方式
  27. rollList.add( new Object());
  28. }
  29. }
  • 1


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

使用synchronized来修饰,此方法相当于单线程队列执行,需要等待,有损性能,好处是不会增加内存的额外开销。

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




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值