List陷阱 写过一次很蠢的代码

ChatProtocolHandler 定义了一个list
 final Map<String, List<IoSession>> pidSessions = new ConcurrentHashMap<String, List<IoSession>>();
 
 
 //该函数设置司机在线
 private void setDidOnline(String did, IoSession session) {
if (this.didSessions.containsKey(did)) {
   List<IoSession>list = this.didSessions.get(did);
   for(IoSession ioss:list){  //这行代码老是抛出 ConcurrentModificationException 异常
   if(ioss.getId() == session.getId()){
   return ;
   }
   else{
    list.add(session);
   }
   }
}
session.setAttribute(SESSION_KEY, did);
List<IoSession>list = new ArrayList<IoSession>();
list.add(session);
this.didSessions.put(did, list);

 }

后来一运行就抛异常,,,,,,,

一直抛ConcurrentModificationException

看这个异常知道是线程安全导致,,,但是我在setDidOnline加了同步关键字,,还是没有效果。。。。。。

后来经高人指点,,,,,才知道自己犯了愚蠢的错误

for(IoSession ioss:list){   //这里迭代的时候会检查list长度是否被修改
    if(ioss.getId() == session.getId()){
    return ;
    }
    else{
      list.add(session);//这里修改了list的长度
    }
    }

单个线程却导致了这个愚蠢的问题,,,,,,,,,,亏我写了这么多年的代码,,,,,


解决方案很简单,,,将List改成ConcurrentHashMap即可。

   private void setDidOnline(String did, IoSession session) {
if (this.didSessions.containsKey(did)) {
   Map<Long, IoSession> mapSessions = this.didSessions.get(did);
   if (mapSessions.containsKey(session.getId())) {
return;
   } else {
mapSessions.put(session.getId(), session);
   }
}
session.setAttribute(SESSION_KEY, did);
Map<Long, IoSession> mapSessions = new ConcurrentHashMap<Long, IoSession>();
mapSessions.put(session.getId(), session);
this.didSessions.put(did, mapSessions);
    }


private final Map<String, Map<Long, IoSession>> didSessions = new ConcurrentHashMap<String, Map<Long, IoSession>>();


分析原因:

1 对list iterator的时候,,,list节点是不允许修改的(iterator remove方法除外)

2 没有细看Iterator源码,,因为心急只是大概猜测下是并发问题,,,这个是程序员修养的问题。遇到问题,,对一些错误不是非常明确,要心平气和把源码看通,,,这样问题就会解开


方案2:

使用CopyOnWriteArrayList 替代 arraylist,因为写array的场景很少,,,大部分都是读操作


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
解题思路: 1. 定义函数`max_min_diff(num)`,用于计算数字重排后的最大值、最小值以及它们的差值。该函数返回一个包含3个元素的元组,分别是最大值、最小值和差值。 2. 定义变量`num`表示输入的三位数。 3. 在一个循环中,每次对`num`进行一次重排求差操作,直到结果为495为止。在每次循环中: - 调用`max_min_diff(num)`函数,获取数字重排后的最大值、最小值和差值; - 输出结果,格式为“序号: 数字重排后的最大数 - 重排后的最小数 = 差值”; - 如果差值为495,则停止循环;否则将差值赋值给`num`,继续下一次循环。 4. 如果输入的三位数三个数字相同,则直接输出“0”。 代码实现: ```python def max_min_diff(num): # 将数字转换为字符串,方便进行重排操作 digits = list(str(num)) digits.sort() # 按照从大到小的顺序组成数字 max_num = int(''.join(digits[::-1])) # 按照从小到大的顺序组成数字 min_num = int(''.join(digits)) # 计算差值 diff = max_num - min_num return max_num, min_num, diff num = int(input()) count = 1 while True: max_num, min_num, diff = max_min_diff(num) print('{}: {} - {} = {}'.format(count, max_num, min_num, diff)) if diff == 495: break num = diff count += 1 if num == 111 or num == 222 or num == 333 or num == 444 or num == 555 or num == 666 or num == 777 or num == 888 or num == 999: print('0') ``` 输入样例: ``` 207 ``` 输出样例: ``` 1: 720 - 27 = 693 2: 963 - 369 = 594 3: 954 - 459 = 495 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值