论坛首页 Java企业应用论坛

关于线程的中处理集合一些问题

浏览 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();//后来加的



测试结果失败 正常的时候还行 不正常又是几十分钟报错
   发表时间: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.
0 请登录后投票
   发表时间: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;
	}
0 请登录后投票
   发表时间: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();
		} 
	}
0 请登录后投票
   发表时间:2015-01-28  
this.stop()这方法不能用
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics