我有一个生产者线程,它将数据提供给消费者,如果我将这些数据打印到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();
}
}
}
}
}
答案 0 :(得分:2)
您的问题是由于两个synchronized
块同时处理同一个锁。它将首先锁定在Runnable
之外,然后再次尝试锁定Runnable
。
synchronized(lock) {
loop = true;
lock.notify();
}
和
synchronized(lock) {
while (!loop) {
lock.wait();
}
}
这可以很容易地转换为:
loop = true;
和
while (!loop) { }