问题
android 线程等待导致死锁
详细问题
为保证线程同步, 使用CountDownLatch倒计时类。主线程等待CountDownLatch倒计时归零程序继续执行
相关代码
为了便于理解, 笔者将问题核心代码提取出来, 如下
package com.example.electronicmall.test.User;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import com.example.electronicmall.R;
import java.util.concurrent.CountDownLatch;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_main_activity);
final CountDownLatch latch = new CountDownLatch(1);
new Thread(new Runnable() {
@Override
public void run() {
// 数据请求线程
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
// 页面更改线程 设计主界面更改
latch.countDown();
}
});
latch.countDown();
}
}).start();
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
解决方案
对于页面更改线程, 调用主线程mHandler的post(Runnabler)方法实现主界面更改
即将上述代码改为
package com.example.electronicmall.test.User;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import androidx.appcompat.app.AppCompatActivity;
import com.example.electronicmall.R;
import java.util.concurrent.CountDownLatch;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_main_activity);
final CountDownLatch latch = new CountDownLatch(1);
// 数据请求线程
new Thread(new Runnable() {
@Override
public void run() {
// 页面更改线程
// MainActivity.this.runOnUiThread(new Runnable() {
// @Override
// public void run() {
// // 页面更改线程
// latch.countDown();
// }
// });//
// 页面更改线程
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
}
});
latch.countDown();
}
});
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
原因
死锁原因
android为每个Activity分配一个主进程, 即Activity.this.runOnUiThread, 出错代码为主进程等待
主进程, 导致死锁
为何调用主线程mHandler的post(Runnabler)方法实现主界面更改
若调用Activity.this.runOnUiThread线程导致死锁
若调用runOnUiThread线程由于涉及主页面修改,android 认为该操作不安全, 控制台报错
对于非主线程修改主界面, android 通过调用主线程mHandler的post(Runnabler)方法实现
实现原理
该方法中的Runnable对象会被会加入到mHandler所在线程的Message消息队列中,假设mHandler在主线程中则Runnable 对象中的run方法将会在主线程中运行。所以能够达到更新UI线程的目的。
参考文献
原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈