@linux1s1s
2019-02-15T21:20:29.000000Z
字数 1553
阅读 2285
JavaThread
2015-11
我们知道,Executor
框架可以将任务的提交和任务的执行解耦出来,它是如何做到解耦的,下面会举例子详细说明。说回上面的话题,上面的话题多少有点言过其实,虽然Executor
框架为制定和修改执行策略都提供了相当大的灵活性,但是,也不是所有的任务都是适用相同的执行策略,比如以下几种:
下面将给出其中 依赖性任务的列子
public class ThreadDeadLock {
ExecutorService executor = Executors.newSingleThreadExecutor();
public class RenderPageTask implements Callable<String> {
@Override
public String call() throws Exception {
Future<String> header, footer;
header = executor.submit(new LoadFileTask("header_task"));
Log.i("Channel", "executor.submit(new LoadFileTask(\"header_task\"))");
footer = executor.submit(new LoadFileTask("footer_task"));
Log.i("Channel", "executor.submit(new LoadFileTask(\"footer_task\"))");
String result = header.get() + " " + footer.get();
Log.i("Channel", "result: " + result);
return result;
}
}
public void render() {
executor.submit(new RenderPageTask());
Log.i("Channel", "executor.submit(new RenderPageTask())");
}
public class LoadFileTask implements Callable<String> {
private String loadName;
LoadFileTask(String loadName) {
this.loadName = loadName;
}
@Override
public String call() throws Exception {
return loadName;
}
}
}
然后测试一下
private void loadFileRender() {
final ThreadDeadLock deadLock = new ThreadDeadLock();
deadLock.render();
}
为什么Log.i("Channel", "result: " + result);
没有打印出来,我们先来简单分析一下即可。
RenderPageTask
任务首先在单线程中执行,然后在RenderPageTask
这个任务又提交了LoadFileTask
任务到单线程中去,因为RenderPageTask
依赖LoadFileTask
,而单线程中LoadFileTask
只能在RenderPageTask
任务结束以后才能有机会得到执行,所以出现了死锁。
所以依赖性任务很容易出现隐性耦合,我们将上面代码L2 简单修改一下,其他不用修改
ExecutorService executor = Executors.newCachedThreadPool();
仅仅修改执行的策略即可,其他不用修改,是不是体会到任务的提交和任务的执行完全解耦了啊
修改为多线程情况下,死锁得到解除。