0

我正在使用一个使用两个线程来读取数据并将数据发送到服务器的应用程序。每个线程运行一个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%。如果您需要更多信息,请告诉我。

4

1 回答 1

0

你的实现的问题是你基本上是在忙着等待——如果没有要发送的东西,它会立即转到异常处理程序并再次尝试——从而占用了该核心上的所有 cpu。

相反,您想要的是一种等待事件可用的方法。我建议您创建一个HandlerThread,并使用与该线程关联的 Handler 来处理对数据流的写入。

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 时间的繁忙等待)

于 2012-04-22T03:02:45.723 回答