浏览 2487 次
锁定老帖子 主题:关于线程的中处理集合一些问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2015-01-22
//线程1---生产数据 public class DataForWlan extends Thread { private CardReaderForWlan rr; public static Set<String> carIdAndTimeSet = Collections.synchronizedSet( new HashSet<String>()); public Set<String> getCarIdAndTimeSet() { return carIdAndTimeSet; } public void setCarIdAndTimeSet(Set<String> carIdAndTimeSet) { this.carIdAndTimeSet = carIdAndTimeSet; } // 初始化线程类 private void init() { try { rr = new CardReaderForWlan(); //创建无线读卡连接 } catch (ReaderException e) { e.printStackTrace(); return; } if (rr == null) { return; } } public synchronized void run() { init(); try { while (true) { TagReadData[] trd = rr.MultiReadCard(); //不断的读卡 但不一定每时每刻都有数据产生 if (trd.length > 0) { readCar(trd); } //this.sleep(5); } } catch (Exception e) { this.stop(); e.printStackTrace(); } } /** * 处理需要的数据 */ public void readCar(TagReadData[] trd) { try { int trdLength = trd.length; if (trdLength <= 0) { return; } for (int i = 0; i < trdLength; i++) { String cardID = trd[i].EPCHexstr(); //卡ID String carIdAndTime = cardID +","+ System.currentTimeMillis()/1000;//用于线程2处理数据用 carIdAndTimeSet.add(carIdAndTime);//短时间内会读一张卡几次,但只需要一结果即可 } } catch (Exception e) { e.printStackTrace(); } } /** * 清空数据 */ public void clearcarIdAndTimeSet(){ carIdAndTimeSet.clear(); } } 线程2 public class MainJFrame extends javax.swing.JFrame implements ActionListener , Runnable{ public Set<String> carIAndTime =null;//读到的卡号存放 public Set<String> cardIdlist = new HashSet<String>();//显示面板存放卡号 private Map<String, Long> map = new ConcurrentHashMap<String,Long>(); public DataForWlan dfw= new DataForWlan ();//无线读卡器线程 public void run() { while (true) { try { carIAndTime = new HashSet<String>(); carIAndTime.addAll(dfw.getCarIdAndTimeSet());//将线程1中的值赋值给carIAndTime dfw.clearcarIdAndTimeSet();//清空数据 if(carIAndTime.size()!=0){ Iterator<String> iterator = carIAndTime.iterator(); while(iterator.hasNext()){ String cardTime = iterator.next(); String [] strs = cardTime.split("[,]"); String cardID = strs[0];//卡ID user = listAllUsers.get(strs[0]);//根据卡ID得到签到人员 if(user != null){ long time = Long.valueOf(strs[1]); Iterator<String> keys = map.keySet().iterator(); if(keys.hasNext()){//以下是做业务处理可以忽略 boolean re = isExist(map, cardID); if(re){//存在 long aftertime = map.get(cardID);//前一个时间 if (time - aftertime > 30) { map.put(strs[0], Long.valueOf(strs[1])); cardIdlist.add(strs[0]); } }else{ map.put(strs[0], Long.valueOf(strs[1])); cardIdlist.add(strs[0]); } }else{ map.put(strs[0],Long.valueOf(strs[1])); cardIdlist.add(strs[0]); } setCarIdOfTime(cardIdlist);//将得到数据,进行业务处理 cardIdlist.clear(); iterator.remove();//后来加的 } } } Thread.currentThread().sleep(600); } catch (InterruptedException e) { e.printStackTrace(); } } } public boolean isExist(Map<String, Long> map, String abc){ boolean isexit = false; Iterator<String> keys = map.keySet().iterator(); if(keys.hasNext()){ while (keys.hasNext()) { String key = (String)keys.next(); if (abc.equals(key)) {//判断此卡号在map中不存在 return true; } } } return isexit; } } 运行几个小时后报错如下。有的时候几十分钟也会报这个错误 这个错误也是我最常看到的,经常出现。 Exception in thread "Thread-4" java.util.ConcurrentModificationException at java.util.HashMap$Hash Iterator.nextEntry(Unknown Source) at java.util.HashMap$KeyIterator.next(Unknown Source) at java.util.AbstractCollection.addAll(Unknown Source) at indexframes.MainJFrame.run(MainJFrame.java:380) at java.lang.Thread.run(Unknown Source) //380行就是线程2中的 carIAndTime.addAll(dfw.getCarIdAndTimeSet()); 但是在线程2中添加下面代码后已经跑了12个小时。还在测试中 iterator.remove();//后来加的 测试结果失败 正常的时候还行 不正常又是几十分钟报错 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2015-01-23
最后修改:2015-01-23
1. 好像你的 "carIAndTime" is not synchronized.
2. dfw.getCarIdAndTimeSet(), the original data is changed during the process of addAll(). I think the #2 is probably the cause. Try to make a copy of the "data" you want to addAll(), and then add them to the carIAndTime. |
|
返回顶楼 | |
发表时间:2015-01-24
public void run() { while (true) { try { carIAndTime = new HashSet<String>(); synchronized (carIAndTime) { carIAndTime.addAll(mfw.getCarIdAndTimeSet());//面板显示的数据信息 mfw.clearcarIdAndTimeSet();//清空数据 if(carIAndTime.size()!=0){ Iterator<String> iterator = carIAndTime.iterator(); while(iterator.hasNext()){ String cardTime = iterator.next(); String [] strs = cardTime.split("[,]"); String cardID = strs[0];//卡ID user = listAllUsers.get(strs[0]);//根据卡ID得到签到人员 if(user != null){ long time = Long.valueOf(strs[1]); //map !=null && !map.isEmpty() //Iterator<String> keys = map.keySet().iterator(); if(map != null && !map.isEmpty()){ for(int i=0; i<map.size(); i++){ boolean re = isExist(map, cardID); if(re){//存在 long aftertime = map.get(cardID);//前一个时间 if (time - aftertime > 8) { map.put(strs[0], Long.valueOf(strs[1])); cardIdlist.add(strs[0]); } }else{ map.put(strs[0], Long.valueOf(strs[1])); cardIdlist.add(strs[0]); } } } //if(keys.hasNext()){ //} else{ map.put(strs[0],Long.valueOf(strs[1])); cardIdlist.add(strs[0]); } //System.out.println("===========当前签到人数:"+map.size()); setCarIdOfTime(cardIdlist); cardIdlist.clear(); } } } } this.tongji(); Thread.currentThread().sleep(600); } catch (InterruptedException e) { System.err.println("run:"+new Date()); e.printStackTrace(); } } } public boolean isExist(Map<String, Long> map, String abc){ return map.get(abc) != null; } |
|
返回顶楼 | |
发表时间:2015-01-24
public void run() { init(); try { while (true) { synchronized (carIdAndTimeSet) { TagReadData[] trd = rr.MultiReadCard(); //读卡 if (trd.length > 0) { readCar(trd); } this.sleep(5); } } } catch (Exception e) { this.stop(); System.err.println(new Date()); System.err.println(e+">>>>>>>>>>>>>"); e.printStackTrace(); } } |
|
返回顶楼 | |
发表时间:2015-01-28
this.stop()这方法不能用
|
|
返回顶楼 | |