@linux1s1s
2019-02-15T13:20:29.000000Z
字数 1553
阅读 2616
JavaThread 2015-11
我们知道,Executor框架可以将任务的提交和任务的执行解耦出来,它是如何做到解耦的,下面会举例子详细说明。说回上面的话题,上面的话题多少有点言过其实,虽然Executor框架为制定和修改执行策略都提供了相当大的灵活性,但是,也不是所有的任务都是适用相同的执行策略,比如以下几种:
下面将给出其中 依赖性任务的列子
public class ThreadDeadLock {ExecutorService executor = Executors.newSingleThreadExecutor();public class RenderPageTask implements Callable<String> {@Overridepublic 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;}@Overridepublic 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();
仅仅修改执行的策略即可,其他不用修改,是不是体会到任务的提交和任务的执行完全解耦了啊
修改为多线程情况下,死锁得到解除。
