mainActivity.runOnUiThread更新表中的数据太慢

时间:2015-06-11 14:42:32

标签: android multithreading concurrency

我有一个生产者线程,它将数据提供给消费者,如果我将这些数据打印到logcat,它可以非常快速地工作。一旦我尝试使用runOnUiThread在ui中更新我的表,就会显示一些数据,等待任意数量的时间然后继续更新直到完成。而不是一秒钟,这个过程可能需要几分钟。

public class DeviceFragment extends Fragment {
static Boolean loop = true;
static Object lock = new Object();
static SnmpPdu pdu;

//handlers initialized in onCreate

@Override
public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        final SnmpWalk snmpWalk = new SnmpWalk(ipAddress, PDUs, lock);
        looperThreadProducerHandler.post(snmpWalk);
        looperThreadConsumerHandler.post(new Runnable() {
                    @Override
                    public void run() {

                        while (snmpWalk.getWalkStart()) {
                            synchronized(PDUs) {
                                if (PDUs.size() != 0) {
                                    pdu = PDUs.remove(0);
                                    Log.d("test", "" + pdu.toString());//this will print fine if i don't call the doWork method
                                    try {
                                        doWork(pdu); //display to ui
                                    } catch (InterruptedException e) {
                                        e.printStackTrace();
                                    }

                                }
                            }

                        }
                    }
                    public void doWork(SnmpPdu pdu) throws InterruptedException {
                        final TableLayout deviceTable = (TableLayout) getView().findViewById(R.id.deviceTable);
                        final TableRow row = new TableRow(getActivity());
                        //skip row initalizers here
                        loop = false;
                        mainActivity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                deviceTable.addView(row);
                                synchronized(lock) {
                                    loop = true;
                                    lock.notify();
                                }

                            }
                        });
                        synchronized(lock) {
                            while (!loop) {
                                lock.wait();
                            }
                        }
                    }
         }
}

1 个答案:

答案 0 :(得分:2)

您的问题是由于两个synchronized块同时处理同一个锁。它将首先锁定在Runnable之外,然后再次尝试锁定Runnable

synchronized(lock) {
    loop = true;
    lock.notify();
}

synchronized(lock) {
    while (!loop) {
        lock.wait();
    }
}

这可以很容易地转换为:

loop = true;

while (!loop) { }