如何在使用生产者 - 消费者类型队列时避免出列线程中的高CPU利用率

时间:2018-04-05 05:41:35

标签: android sockets queue cpu-usage blockingqueue

我正在使用UDP套接字形式,其中数据包被排入链接阻塞队列在android中。对于单个队列,使用2个线程,一个线程负责队列中的队列以及其他队列元素。对于enqueue和dequeue线程,使用while(true)循环。但是,排队主题中的while(true)不会消耗大量内存,如android studio profiler中所示。我的猜想是,这是由于阻挡udpSocket.receive(packet)性质的性质。最好的部分是,while(true)的排队线程占用了~0%的内存,如android profiler所示。但是,dequeuing thread消耗了大约15%的内存,如下面的屏幕截图所示。出列线程的代码片段如下所示

 while (true) {

            if (!linkedBlockingQueue_A.isEmpty()) {

                String  data = (String) linkedBlockingQueue_A.element();

//                System.out.println(data);

                // parsing the data
                String[] tupleData =  data.split(",");
                Integer sensor_id = Integer.valueOf(tupleData[0]);
                Integer tuple_id = Integer.valueOf(tupleData[1]);
                Long generation_time = Long.valueOf(tupleData[4]);
                Long sensor_data = Long.valueOf(tupleData[5]);
                Long event_arrival_time = Long.valueOf(tupleData[6]);
                Long event_ingestion_time = nanoTime();


//              define stream ecg_stream (sensorID int, tupleID int, ecg_value float , event_ingestion_time_ecg long, event_arrival_time_ecg long);";

                        // sending data to siddhi server
                   inputHandlerA.send(new Object[]{sensor_id, tuple_id, sensor_data,generation_time, event_arrival_time ,  event_ingestion_time });

                linkedBlockingQueue_A.remove();
            }

我认为需要的是出队线程中的一些阻塞性质,以避免因轮询而导致的内存消耗。当我使用多个套接字时,我的设备"谷歌像素"经过几个小时的操作后,它太热了,我不得不把它关闭几个小时。

欢迎任何建议

enter image description here

1 个答案:

答案 0 :(得分:0)

这个问题已经解决,因为我发现queue.take()正是我所寻找的。当它检索并删除由此双端队列表示的队列的头部(换句话说,此双端队列的第一个元素)时,必要时等待,直到元素变为可用。以下是更新后的代码。

        while (true) {

                String  data = (String) linkedBlockingQueue_A.take();


                // parsing the data
                String[] tupleData =  data.split(",");
                Integer sensor_id = Integer.valueOf(tupleData[0]);
                Integer tuple_id = Integer.valueOf(tupleData[1]);
                Long generation_time = Long.valueOf(tupleData[4]);
                Long sensor_data = Long.valueOf(tupleData[5]);
                Long event_arrival_time = Long.valueOf(tupleData[6]);
                Long event_ingestion_time = nanoTime();


//              define stream ecg_stream (sensorID int, tupleID int, ecg_value float , event_ingestion_time_ecg long, event_arrival_time_ecg long);";

                        // sending data to siddhi server
                   inputHandlerA.send(new Object[]{sensor_id, tuple_id, sensor_data,generation_time, event_arrival_time ,  event_ingestion_time });
//
           }

对于相同的while(true),由于take()方法的阻止/等待性质,利用率很低

enter image description here