Android mainActivity.runOnUiThread更新表中数据的速度太慢
我有一个生产者线程,它将数据提供给消费者,如果我将这些数据打印到logcat,它的工作速度非常快。只要我尝试使用runOnUiThread更新ui中的表,就会显示一些数据,等待任意时间,然后继续更新,直到完成为止。这一过程可能需要几分钟,而不是一秒钟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
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) { }