一个静态变量,特定情况才需要实例化.

private static ConcurrentMap<String, String> table2entity = null; //静态变量,特定情况才需要实例化.

static ConcurrentMap<String, String> getTable2entityMap() { 
        if (table2entity == null) {
            table2entity = new ConcurrentHashMap<>();
            initTable2Entity();
        }

return table2entity;
    }

用Find Bugs检测, 会报:

Incorrect lazy initialization of static field.

Incorrect lazy initialization of static field org.xxx.Abc.table2entity in org.xxx.Abc..getTable2entityMap() [Troubling(14), Normal  confidence]

主要原因是线程安全问题。多线程有可能会对该方法调用造成实例化多次。在该方法加synchronized,错误就可消除。但synchronized效率不高。

后来改成加自定义锁,

//private static byte lock[] = new byte[0];

private static final byte lock[] = new byte[0];

static ConcurrentMap<String, String> getTable2entityMap() { //just create the Javabean files would use
        if (table2entity == null) {
            synchronized (lock) {
                if (table2entity == null) {
                    table2entity = new ConcurrentHashMap<>();
                    initTable2Entity();
                }
            }
        }
        return table2entity;
    }

然后Find Bugs看不懂了,报了以下错误, 认为作了双重检测了。

Possible doublecheck on Field.

Possible doublecheck on org.xxx.Abc.table2entity in org.xxx.Abc..getTable2entityMap()[Troubling(14), Normal confidence]

到这里,假如认为,这是Find Bugs自己的bug, 那就需要了解另一个概念了——Java多线程双重加锁  , 及可能问题.

例子:

(指令重排优化导致)

private static ActivityLifeManager sInstance;public static ActivityLifeManager getInstance() {if (sInstance == null) {synchronized (ActivityLifeManager.class) {if (sInstance == null) {sInstance = new ActivityLifeManager();}}}return sInstance;
}

双重加锁可能存在的一个问题就是

例如线程1已经分配了地址给instance 但是还没有初始化, 此时线程2 判断intance不是null 直接返回

解决:
volatile的一个语义是禁止指令重排序优化,也就保证了instance变量被赋值的时候对象已经是初始化过的,从而避免了上面说到的问题。

对于可见性,Java提供了volatile关键字来保证可见性。

  当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。

一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

  1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

  2)禁止进行指令重排序。

但是用volatile修饰之后就变得不一样了:

  第一:使用volatile关键字会强制将修改的值立即写入主存;

  第二:使用volatile关键字的话,当线程2进行修改时,会导致线程1的工作内存中缓存变量stop的缓存行无效(反映到硬件层的话,就是CPU的L1或者L2缓存中对应的缓存行无效);

  第三:由于线程1的工作内存中缓存变量stop的缓存行无效,所以线程1再次读取变量stop的值时会去主存读取。

另外需要注意:volatile没办法保证对变量的操作的原子性。

最终改为如下:

private static volatile ConcurrentMap<String, String> table2entity = null;

static ConcurrentMap<String, String> getTable2entityMap() {
        if (table2entity == null) {
//            synchronized (HoneyContext.class) {
            synchronized (lock) {
                if (table2entity == null) {
                    table2entity = new ConcurrentHashMap<>();
                    initTable2Entity();
                }
            }
        }
        return table2entity;
    }

至此,错误提示消失。

Find Bugs自己的bug. Find Bugs‘ bug.相关推荐

  1. 后端拼接html能做判断吗,怎么判断是前端bug还是后端bug?

    在提bug时,只有明确定位是前端bug还是后端bug,才能正确指派给对应的开发同学,如果经常分不清楚,一直需要开发同学重新指派,不仅浪费了时间,还会被开发同学吐槽,今天就带大家解锁一些区分前后端bug ...

  2. 如何区分前端BUG和后端BUG

    1.如何区分前端和后端 通俗讲,用户看到的部分都叫前端. 而用户看不到的部分可以统称为后端. 2.前端和后端的呈现形式 前端的呈现形式有web端.移动端(ios.安卓).小程序等. 后端系统一般只有一 ...

  3. 【判断是前端bug还是后端bug】

    判断是前端bug还是后端bug 一.界面相关,排版错乱,文案错误等问题,大都属于前端bug 1.出现样式的问题基本都是CSS的bug 2.出现文本的问题基本都是html的bug 3.出现交互类的问题基 ...

  4. 软件测试Bug,你是怎么找bug的?bug分析的正确打开方式......

    目录:导读 前言 一. bug详细 二.获取bug具体数据 三.有效的管理bug 四.做好bug分析工作 五.深入bug分析 六.总结 前言 Bug严重级别(Severity,Bug级别):是指因缺陷 ...

  5. 软件测试无效bug分析,(一)Bug不能重现的原因分析及其对策

    摘 要:本文简要分析了无法重现的Bug的可能产生原因,包括环境不一致.缺少最准确的描述和浏览器的不当设置.针对这些原因,本文给出了相应的对策.通过这些措施,可以重现许多以前认为不可重现的Bug. 关键 ...

  6. 软件测试(基础)· 软件测试的生命周期 · 如何描述一个 Bug · Bug 的级别 · Bug 的生命周期 · 争执 · Bug 评审

    一.软件测试的生命周期 软件测试的生命周期 & 软件开发的生命周期 二.如何描述一个 Bug 三.如何定义 Bug 的级别 四.Bug 的生命周期 五.发生争执了怎么办? Bug 评审 一.软 ...

  7. 测试中BUG定义、测试BUG的等级划分、Bug流程以及Bug解决优先级

    一个优秀的软件测试师不仅仅能够发现软件中的bug,还能分析出bug产生的原因. 总结了一些软件测试入门必须要了解和学习的BUG基础知识,主要包括BUG定义.测试BUG的等级划分.Bug流程以及Bug解 ...

  8. php bug 管理系统,BugFree(Bug跟踪管理系统) v3.0.3

    BugFree 3.0 在保留 2.x 版本的用户体验基础上进行了完全的重构和重写,重点突出了可配置.可定制和交互性.我们在2.x 版本的兼容和升级上做了大量的工作,但毕竟是一次完全的技术重构,系统稳 ...

  9. 王者荣耀服务器维护5.3,王者荣耀3月5日更新修复5个bug 王者荣耀bug修复介绍

    王者荣耀在3月5日再次进行了更新,这次更新不仅上线了N多福利,而且还对游戏进行了调整,更是一口气修复了游戏中的5个bug.那么,王者荣耀最新修复了哪些bug呢?bug修复后有什么好处呢? 王者荣耀3月 ...

最新文章

  1. vue单选,多选,多选的内容显示在页面可删除
  2. 争对让望对思野葛对山栀注解_笠翁对韵.支_李召洋、于婷、杨盼兮、于婷_高音质在线试听_笠翁对韵.支歌词|歌曲下载_酷狗音乐...
  3. 【学习笔记】25、关系数据库存储
  4. 美学设计评价_死亡的孩子无法使用的设计美学
  5. mysql数据库熟悉表空间数据文件_Oracle表空间和数据文件
  6. SQL优化之一则MySQL中的DELETE、UPDATE 子查询的锁机制失效案例
  7. iOS 评论APP撰写评论
  8. 【图像处理】【去模糊】图像去模糊之初探--Single Image Motion Deblurring
  9. c语言char数字转int补位,如何补位??
  10. 嘉立创PCB CAM软件
  11. “防疫情、稳经济、保安全”大走访 大排查 | 上海铭控篇
  12. 小程序开发工具_小程序开发工具都有哪些?
  13. 挖出api接口的重要性
  14. joomla速度优化_WordPress v Joomla:搜索引擎优化
  15. 音频设置 audio
  16. 【数据结构复习】二叉树的遍历——从微软2014校园招聘说起
  17. vue路由——基础篇(二)
  18. ¥3EG踩坑记录¥Vitis HLS xfopencv库的安装解决minGW32-make 编译opencv时 error
  19. 微信小程序JS中写Json解析for 数组的用法
  20. 无法定位程序输入点_invalid_parameter_noinfo_noreturn于动态链接库 MSVCR100.dll上

热门文章

  1. CSS的基础选择器、字体属性、文本属性和引入方式
  2. python爬取网站的某一句话,python正则爬取某段子网站前20页段子(request库)过程解析...
  3. CSS基本知识及帮助文档
  4. 淮北大学计算机科学与技术,淮北师范大学计算机科学与技术学院2020年硕士研究生调剂复试工作实施细则...
  5. 创维电视显示连接服务器失败怎么回事,网络出错(50101,1401001)是什么意思-创维电视网络异常101...
  6. 蓝牙测试指标有哪些?
  7. 3dmax雨伞模型应该如何建模
  8. vulnhub - digitalworld.local: MERCY v2 (考点:信息搜集 smb 端口敲门 RIPS tomcat linux 提权)
  9. 搭建 JumpServer 堡垒机管理数万台游戏服务器
  10. 怎么隐藏计算机回收站之类的,怎么隐藏回收站 隐藏回收站方法【图文】