首页 > Java开发 > 并发情况下synchronized死锁

并发情况下synchronized死锁

存在缺陷的代码:

 

[java][/java] view plaincopyprint?

  1. public class DataPropertyIdAndNameRepositoryImpl{
  2.     /** 发布标志 */
  3.     private volatile boolean                      publishFlag;
  4.     public Integer getStandardId(int dataId, String propertyName) {
  5.         if (!publishFlag) {
  6.             loadToCache();
  7.         }
  8.         Integer standardId = 0;
  9.         Map<String, Integer> propertyIdMap = propertyIdLocalCache.get(dataId);
  10.         if (propertyIdMap != null) {
  11.             standardId = propertyIdMap.get(propertyName);
  12.         }
  13.         return standardId;
  14.     }
  15.     public synchronized boolean loadToCache() {
  16.         try {
  17.             DataPropertyIdAndName dataPropertyIdAndName = dataPropertyIdAndNameService
  18.                 .queryDataPropertyIdAndName();
  19.             publishFlag = true;
  20.         } catch (Exception e) {
  21.             publishFlag = false;
  22.         }
  23.         return publishFlag;
  24.     }
  25. }

 

 

存在缺陷的流程:

a. 绿色表示第一个线程,蓝色表示第二个线程。

b. 黄色模块的代码为synchronized标记的代码,并发情况下只会有一个线程执行此方法。

c. 绿色线程执行到紫色模块时,蓝色线程等待进入黄色模块。

d. 蓝色线程执行抛异常,导致publishFlag被置为false。

e. 此时再次有线程进入,判断publishFlag仍为false,因此导致重复不断加载loadToCache.

 

修复后的代码:

 

[java][/java] view plaincopyprint?

  1. public class DataPropertyIdAndNameRepositoryImpl{
  2.     /** 发布标志 */
  3.     private volatile boolean                      publishFlag;
  4.     public Integer getStandardId(int dataId, String propertyName) {
  5.         if (!publishFlag) {
  6.             loadToCache();
  7.         }
  8.         Integer standardId = 0;
  9.         Map<String, Integer> propertyIdMap = propertyIdLocalCache.get(dataId);
  10.         if (propertyIdMap != null) {
  11.             standardId = propertyIdMap.get(propertyName);
  12.         }
  13.         return standardId;
  14.     }
  15.     public synchronized boolean loadToCache() {
  16.         try {
  17.             // 双检锁
  18.             if (publishFlag) {
  19.                 return publishFlag;
  20.             }
  21.             DataPropertyIdAndName dataPropertyIdAndName = dataPropertyIdAndNameService.queryDataPropertyIdAndName();
  22.             publishFlag = true;
  23.         } catch (Exception e) {
  24.             publishFlag = false;
  25.         }
  26.         return publishFlag;
  27.     }
  28. }

本文固定链接: http://www.devba.com/index.php/archives/2864.html | 开发吧

报歉!评论已关闭.