当前位置:网站首页>Runnable是否可以中断
Runnable是否可以中断
2022-07-07 13:20:00 【我不勤奋v】
背景:楼主在项目开发中遇到一个问题,在Activity中需要起一个子线程执行耗时任务,Activity退出onDestroy后,释放资源。刚好子线程执行耗时任务的时候需要访问被释放的资源,进而发生了空指针异常的崩溃。
原因:主线程和子线程是并发的,主线程Activity何时退出释放资源,子线程何时访问资源,两者时序不可控。
1)加锁可以吗?
主线程Activity退出 释放资源时候加锁,;子线程执行Runnable时加锁,并且子线程执行任务之前判断是否已经释放资源。
这样可能会导致ANR问题:万一子线程耗时任务很久,主线程退出Activity时由于锁被子线程持有一直等待,有ANR风险。
2) 不加锁,使用volatile关键字标记是否释放变量
主线程退出Activity时,volatile变量 设置为true代表已经释放。子线程的runnable 执行之前判断volatile变量的值,如果为true代表资源是否,不再执行。
上线后依旧有零星崩溃上报:子线程的runnable判断volatile变量时候,资源还没释放。执行后续的逻辑,资源释放了造成崩溃。
时序: 子线程判断volatile变量,通过——主线程释放资源——子线程后续的逻辑访问资源
于是楼主想到,主线程退出Activity时,应该释放生命周期内使用的资源,包括子线程的Runnable,让Runnable不执行或者中断。——但是真的可以中断吗?
- 有人说Handler的removeCallbacksAndMessages——对于未执行的Runnable,可以,但是对于已经跑起来的Runnable, 不行。
- 有人说Thread.interrupt, 但是interrupt仅仅起到通知被停止线程的作用,实际上对于被停止的线程而言,它拥有完全的自主权,它既可以选择立即停止,也可以选择一段时间后停止,也可以选择压根不停止。——这个是Java 不提供强制停止线程机制。
- 有人说线程池的shutdownNow方法,但是shtdownNow方法本质也还是给正在执行的线程发送interrupt。
- 有人说使用线程池的Submit(Runnable runnable) 返回一个Future, 最后通过Future的cancel方法不就可以了??——楼主亲测,跑起来的Runnable 还是不行。
以上尝试,使用如下Demo验证, Activity Destroy后,Runnable依旧执行......
public class TestActivity extends Activity {
private Runnable runnable;
private HandlerThread handlerThread;
private Handler handler;
private Thread thread;
private Future future;
private ExecutorService executorService;
private Handler mainHandler = new Handler(Looper.getMainLooper());
public static void startActivity(Context context) {
Intent intent = new Intent(context, TestActivity.class);
context.startActivity(intent);
}
private void init() {
runnable = new Runnable() {
@Override
public void run() {
while (true) {
try{
Thread.sleep(1000);
Log.e("testing", "runnable run...." + TestActivity.this);
} catch (Exception e) {
Log.e("testing", "e run...." + e.toString());
}
}
}
};
//1. handlerThread
// handlerThread = new HandlerThread("test-handler-thread");
// handlerThread.start();
// handler = new Handler(handlerThread.getLooper());
// handler.post(runnable);
//2. Thread
// thread = new Thread(runnable);
// thread.start();
//3. future
executorService = Executors.newSingleThreadExecutor();
future = executorService.submit(runnable);
}
private void release() {
//1.handlerThread
// handlerThread.quit();
// handler.removeCallbacks(runnable);
//2. Thread
// try {
// thread.interrupt();
// } catch (Exception e) {
// }
//3. future
if(future != null) {
boolean ret = future.cancel(true);
executorService.shutdown();
Log.e("testing", "future cancel...." + ret);
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
Log.e("testing", "act onCreate ");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
init();
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TestActivity.this.finish();
}
});
}
@Override
protected void onDestroy() {
release();
Log.e("testing", "act onDestroy ");
super.onDestroy();
}
}
实际上,JAVA 推荐了使用Thread.currentThread().isInterrupted()的方法判断线程是否中断
也就是Demo中Runnable的 while(true) 修改为while(!Thread.currentThread().isInterrupted())
就Demo而言,可以实现中断Runnable, 但是实际项目的Runnable并不是一直循环,大多是一个耗费时间的任务。 Thread.currentThread().isInterrupted()判断不能一直贯穿整个Runnable, 只能在某一个时刻调用——万一在Runnable里调用isInterrupted()的时候线程还没interrupt, 调用isInterrupted()判断过后线程才interrupt, runnable仍然访问被释放的资源。
边栏推荐
- CTFshow,信息搜集:web7
- 一个需求温习到的所有知识,h5的表单被键盘遮挡,事件代理,事件委托
- [deep learning] image hyperspectral experiment: srcnn/fsrcnn
- 有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?
- 2022年5月互联网医疗领域月度观察
- Niuke real problem programming - Day12
- @Introduction and three usages of controlleradvice
- 【目标检测】YOLOv5跑通VOC2007数据集
- 微信小程序 01
- Ctfshow, information collection: web1
猜你喜欢
广州开发区让地理标志产品助力乡村振兴
IDA pro逆向工具寻找socket server的IP和port
Apache multiple component vulnerability disclosure (cve-2022-32533/cve-2022-33980/cve-2021-37839)
[server data recovery] data recovery case of raid failure of a Dell server
Summer safety is very important! Emergency safety education enters kindergarten
如何在opensea批量发布NFT(Rinkeby测试网)
Unity's ASE realizes cartoon flame
CTFshow,信息搜集:web10
Mathematical modeling -- what is mathematical modeling
Write a ten thousand word long article "CAS spin lock" to send Jay's new album to the top of the hot list
随机推荐
连接ftp服务器教程
Several ways of JS jump link
13 ux/ui/ue best creative inspiration websites in 2022
什麼是數據泄露
Shengteng experience officer Episode 5 notes I
Infinite innovation in cloud "vision" | the 2022 Alibaba cloud live summit was officially launched
MongoDB数据库基础知识整理
PG basics -- Logical Structure Management (locking mechanism -- table lock)
[server data recovery] a case of RAID data recovery of a brand StorageWorks server
Classification of regression tests
【數據挖掘】視覺模式挖掘:Hog特征+餘弦相似度/k-means聚類
Ctfshow, information collection: web4
Niuke real problem programming - day15
【搞船日记】【Shapr3D的STL格式转Gcode】
众昂矿业:萤石继续引领新能源市场增长
[deep learning] image hyperspectral experiment: srcnn/fsrcnn
Used by Jetson AgX Orin canfd
TypeScript 发布 4.8 beta 版本
什么是数据泄露
CTFshow,信息搜集:web7