Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/225.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android mainActivity.runOnUiThread更新表中数据的速度太慢_Android_Multithreading_Concurrency - Fatal编程技术网

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

Android mainActivity.runOnUiThread更新表中数据的速度太慢,android,multithreading,concurrency,Android,Multithreading,Concurrency,我有一个生产者线程,它将数据提供给消费者,如果我将这些数据打印到logcat,它的工作速度非常快。只要我尝试使用runOnUiThread更新ui中的表,就会显示一些数据,等待任意时间,然后继续更新,直到完成为止。这一过程可能需要几分钟,而不是一秒钟 public class DeviceFragment extends Fragment { static Boolean loop = true; static Object lock = new Object(); static SnmpPdu

我有一个生产者线程,它将数据提供给消费者,如果我将这些数据打印到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();
                            }
                        }
                    }
         }
}

您的问题是由于两个
同步的
块同时在同一个锁上工作。它将首先在
Runnable
外部锁定,然后再次尝试在
Runnable
内部锁定

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

这可以轻松地转换为:

loop = true;


为什么有“锁定”的同步块?什么是线程安全?java.lang.IllegalMonitorStateException:对象在notify()之前未被线程锁定,因此我需要同步锁,我需要数据有序。因此,我试图实现顺序执行。如果您删除同步、通知和等待,并且在添加视图后有一个停用的while循环,那么您应该有一个顺序?另外,请尝试查找doWork方法花费大部分时间的位置。放入一些日志以确定在各种代码块上花费了多少时间。在主线程中使用阻塞while循环是不好的做法。尽管我去掉了所有的同步块,数据还是井然有序。我猜过于偏执于线程安全可能会引起回击。谢谢你的帮助
loop = true;
while (!loop) { }