正在做一个netty服务端,业务是这样的:客户端发数据给服务端,服务端收到之后发一条反馈数据回去;另外服务端需要实时查询数据库,如果有数据就发送给对应客户端,5秒循环一次,我把这两个业务写在同一个channelRead中,结果后者经常出现多次发送数据的情况,好像是多个线程都在执行这个循环,执行的周期不是5秒,5秒内执行了多次,也就是一条数据发了多次且次数不定,不知道是哪里的问题,感觉是自定义线程runnable和netty线程组之间没有协调工作,不知道怎么解决
public class MyHandler extends ChannelHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception
{
01接收客户端数据,并给予反馈,代码略
//02每五秒钟自动遍历一次数据库,将策略数据发送至指定客户端
Runnable send = new Runnable() {
@Override
public void run() {
Mysend:
//for无限循环
for(;;)
{
try{
Convertion con=new Convertion();
gettacticsdata data=new gettacticsdata();
//读取存储在Map中已登录用户ID
Map<String, SocketChannel> map = Mymap.getChannels();
Iterator<String> it = map.keySet().iterator();
//for(int m=0;m<map.size();m++)
while (it.hasNext())
{
System.out.println("Map集合大小为:"+map.size());
String key = it.next();
System.out.println("key:"+key);
SocketChannel obj = map.get(key);
//判断当前客户是否在线,如果在线就传数据,不在就删除存储在Map中的登录信息
if(obj.isActive()==true)
{
data.updatelwzt(key);
//查询需要下发的策略B数据
ArrayList Bal=data.GetBdata(key);
//判断是否有需要下发的策略
if(Bal.size()>0)
{
for(int i=0;i<Bal.size();i++)
{
tacticsBdata Bl=(tacticsBdata) Bal.get(i);
byte[] Bdata=con.GetBdata(Bl);
//SocketChannel obj = map.get(key);
if(Bdata.length==32){
ByteBuf Bsend =Unpooled.copiedBuffer(Bdata);
obj.writeAndFlush(Bsend);
}
}
}
}else
{
System.out.println("此ChannelID已掉线: " + obj);
String resultdk=data.updatelwztdk(key);
map.remove(key);
obj.close();
}
}
}
catch(Exception e)
{
break Mysend;
}
try {
//线程休眠5秒钟后再次启动
Thread.sleep(5000);
} catch (InterruptedException e) {
//e.printStackTrace();
}
}
}
};
new Thread(send).start();
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
ctx.close();
}