我正在使用一个使用两个线程的应用程序来读取和发送数据到服务器。每个线程运行一个while循环;一个que包含一系列被命令发送到服务器的命令。通过这种方式,我可以将大量命令排成一行并逐个发送到服务器。
命令发送者就是这样
class writeThread extends AsyncTask<Object, Object, Object>
{
byte[] buffer;
LittleEndianDataOutputStream outputStream;
@Override
protected void onPreExecute()
{
}
@Override
protected Object doInBackground(Object... params)
{
try
{
buffer = new byte[4096];
outputStream = new LittleEndianDataOutputStream(dataHolder.connection.getOutputStream());
try
{
dataHolder.flags latestFlag;
while (true)
{
try
{
latestFlag = dataHolder.sendFlags.remove();
ByteBuffer sendBytes = ByteBuffer.allocate(128);
sendBytes.order(ByteOrder.LITTLE_ENDIAN);
switch (latestFlag)
{
case sendDataRequest:
sendBytes.putInt(20);
outputStream.write(sendBytes.array());
break;
case getSelectedData:
sendBytes.putInt(21);
sendBytes.put(dataHolder.latestSelected.getBytes());
outputStream.write(sendBytes.array());
break;
case disconnect:
sendBytes.putInt(254);
sendBytes.put(dataHolder.latestSelected.getBytes());
outputStream.write(sendBytes.array());
break;
}
}
catch (NoSuchElementException ex){}
}
}
catch (IOException ex) {}
}
catch (Exception ex){};
return null;
}
}
读取循环看起来像
while (inputStream.read() > -1)
因此,应用程序最终会占用手机处理能力的50%。有关如何优化套接字侦听和数据发送的建议吗?
注意:是的我知道我正在使用try catch代替队列而不是if语句来检查队列是否为空。我确信错误抛出并没有帮助优化,但我认为它不会将处理器推向50%。如果您需要更多信息,请告诉我。
答案 0 :(得分:0)
你的实现的问题是你基本上在做一个忙碌的等待 - 如果没有什么可以发送,它立即进入异常处理程序并再次尝试 - 从而占用该核心上的所有cpu。
您想要的是一种等待事件可用的方式。我建议您创建一个HandlerThread,并使用与该线程关联的处理程序来处理对数据流的写入。
HandlerThread handlerThread = new HandlerThread("blah");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper()) {
public boolean HandleMessage(Message msg) {
switch (msg.what) {
case sendDataRequest:
...
case getSelectedData:
...
case disconnect:
...
}
}
}
然后您将使用适当的ID和数据创建消息,并使用handler.sendMessage()
将它们发送给处理程序或者(也许更简单),如果你使dataHolder.sendFlags集合成为一个ArrayBlockingQueue,而不是它当前的任何东西(我猜是ArrayList或类似的?),那么,当你去删除下一个元素时ArrayBlockingQueue.take(),它会等到可用的东西(没有执行占用所有可用CPU时间的忙等待)