netty多线程中使用静态同步hashset不同步的问题

oneccx 发布于 07/13 19:17
阅读 160
收藏 0
//静态hashset
public static Set<Channel> cons = Collections.synchronizedSet(new HashSet<Channel>());

// 当有新连接时
// 1.判断cons中是否存在deviceid相同的channel,如果有则断开之前的连接
// 2.cons中加入新channel
// 3.设置channel的attr为设备id
// 4.更新数据库
isExist(data.getDeviceId());
Server.cons.add(ctx.channel());
Attribute<Integer> deviceID = ctx.channel().attr(Constant.DEVICE_ID);
deviceID.set(data.getDeviceId());
device.setIsConnect(1);
deviceRepository.save(device);
deviceLogRepository.save(new DeviceLog(null, device.getId(), 1, remark, new Date()));

//检查cons中是否存在相同deviceid的channel,有则断开旧连接
private void isExist(Integer deviceId) {
		Iterator<Channel> iterator = Server.cons.iterator();
		while(iterator.hasNext()) {
			Channel next = iterator.next();
			if(deviceId == next.attr(Constant.DEVICE_ID).get()) {
				disconnect(next, "出现新连接");
				return;
			}
		}
	}

//断开连接
private void disconnect(Channel ch, String err) {
		Server.cons.remove(ch);
		try {
			ch.close().sync();
		} catch (InterruptedException e) {
			logger.error(e.getMessage(), e);
		}
		Attribute<Integer> attr = ch.attr(Constant.DEVICE_ID);
		if(attr.get() != null) {
			Optional<Device> deviceOpt = deviceRepository.findById(attr.get());
			Device device = deviceOpt.get();
			device.setIsConnect(0);
			deviceRepository.save(device);
			InetSocketAddress insocket = (InetSocketAddress) ch.remoteAddress();
			String clientIP = insocket.getAddress().getHostAddress();
			String clientPort = String.valueOf(insocket.getPort());
			String tName = Thread.currentThread().getName();
			String remark = String.format("channel: %s, clientAddress: %s:%s, Thread: %s", ch.id().asLongText(), clientIP, clientPort, tName);
			deviceLogRepository.save(new DeviceLog(null, device.getId(), 2, err + " ( " + remark + ")", new Date()));
		}
		logger.error(err + ": " + attr.get());
	}

 

出现了这种情况:

理想情况应该是:18:40:46设备建立新的连接之前旧的设备连接应该先断开,但时日志中没有,我估计是不是hashset中的旧channel因为多线程的原因没有检测到

还请各位大佬指定一下

加载中
0
爱De资格

在返回的 collection 上进行迭代时,用户必须手工在返回的 collection 上进行同步。你的isExist方法结果是不准确的

0
凉茶未凉
凉茶未凉

这个iterator.hasNext()好像不是线程安全的吧?

0
o
oneccx

两次操作相差40多秒,为什么取到的hashset还是不同步呢

0
ffqcode
ffqcode

同顶,遇到了类似问题。

0
独孤晓林

set判断的时候需要锁

返回顶部
顶部