我在多线程期间读取广播数据的流数据捕获中遇到了一个问题,请帮助或建议。
实际上有一个类是从其中一个udp套接字读取数据的。另一个类接受来自每个客户端请求的tcp连接,为每个客户端创建一个线程,并为数据请求相同的udp类。这件事正在与创建的第一个线程一起工作。但是当我从另一个pc/ip向另一个客户端发出请求时,数据包就会丢失到第二个客户端/线程
我已经做了一个变通方法,创建了一个列表来存储对象,并循环将数据发送给所有客户端。但这只是暂时的,因为如果客户端/连接增加,它将延迟数据包。
读取UDP数据的代码
public class EventNotifier
{
private InterestingEvent ie;
public DatagramSocket clientSocket;
public String[] split_str;
byte[] receiveData;
HashMap<String, String> secMap = new HashMap<String, String>();
public EventNotifier(InterestingEvent event)
{
ie = event;
clientSocket = new DatagramSocket(9050);
receiveData = new byte[500];
}
public String getDataFeed(String client_id)
{
try
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String s = new String(receivePacket.getData());
String split_str = s.split(",");
if(secMap.containsValue(split_str[0]))
return s;
else
return "";
} catch(Exception e3) {}
}
}// end of eventNotifier class多线程处理客户端请求的代码
public class multiServer
{
static protected List<PrintWriter> writers = new ArrayList<PrintWriter>();
static String client_id = "";
public static void main(String[] args)
{
try
{
ServerSocket servsock = new ServerSocket(8858);
Socket incoming;
while(true)
{
incoming = servsock.accept();
multiServerThread connection = new multiServerThread(incoming);
Thread t1 = new Thread(connection);
t1.start();
}
}
catch(IOException e)
{
System.out.println("couldnt make socket");
}
}
}
class multiServerThread extends Thread implements InterestingEvent
{
Socket incoming;
PrintWriter out=null;
PrintWriter broad=null;
BufferedReader in = null;
String cliString=null;
private EventNotifier en;
int id;
public static String udp_data;
public void interestingEvent(String str1)
{
this.udp_data = str1;
}
public String getUdpData()
{
String _udp_data = this.udp_data;
return _udp_data;
}
multiServerThread(Socket incoming)
{
this.incoming=incoming;
en = new EventNotifier(this);
}
public void run()
{
try
{
out = new PrintWriter(incoming.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(incoming.getInputStream()));
cliString = in.readLine();
multiServer.writers.add(out);
while(true)
{
try
{
udp_data = en.getDataFeed(cliString);
if(udp_data!=null && udp_data.length()>0)
{
//workaround for serving the data to all cleints who are connected
for (int i=0; i<multiServer.writers.size();i++)
{
broad=multiServer.writers.get(i);
broad.println(udp_data.trim());
}
//else will directly write to the outputstream object for every thread which is connected
// out.println(udp_data.trim());
}
}
catch (Exception e)
{
System.out.println("exception "+e);
}
Thread.sleep(1);
}
} catch(IOException e)
{
System.out.print("IO Exception :: "+ e);
}
catch(InterruptedException e)
{
System.out.print("exception "+ e);
}
}
}发布于 2012-06-25 16:19:04
您需要互斥(或不同的设计)。
例如,如果两个线程并发调用multiServer.writers.add(out);,会发生什么情况?
从ArrayList Javadoc
请注意,此实现不是同步的。如果多个线程并发访问一个ArrayList实例,并且至少有一个线程在结构上修改了列表,则必须在外部同步该实例。(结构修改是添加或删除一个或多个元素的任何操作,或者...)
另一个问题是两个并发调用udp_data = en.getDataFeed(cliString);。第二个线程可能会覆盖第一个线程的结果。你会丢失数据的!
如果一个线程调用for (int i=0; i<multiServer.writers.size();i++),而另一个线程忙于执行multiServer.writers.add(out);,会发生什么?在out被真正添加到列表之前,大小可能已经增加了!
public class multiServer
{
private List<PrintWriter> writers = new ArrayList<PrintWriter>();
public synchronized void addWriter(PrintWrite out) {
writers.add(out);
}
public synchronized void serveAllWriters(String data) {
for (int i=0; i<multiServer.writers.size();i++)
{
broad=multiServer.writers.get(i);
broad.println(data);
}
}
}现在,当一个线程试图添加一个写入器时,synchronized将确保没有其他线程正在add或打印。因此,应该修复multiServerThread以使用新方法:
class multiServerThread extends Thread implements InterestingEvent
{
//...
private String udp_data;
//...
myMultiServer.addWriter(out);
//...
udp_data = en.getDataFeed(cliString);
if(udp_data!=null && udp_data.length()>0)
myMultiServer.serveAllWriters(udp_data.trim());
//...
}可能会有更多的问题,不确定我没有完全理解你的代码。您必须问自己的问题是,另一个线程是否可以读取和/或写入相同的数据或对象?是?那么你将需要适当的同步。
https://stackoverflow.com/questions/11184427
复制相似问题