5
回答
Executors.newCachedThreadPool() 无界线程池诡异问题,大家赐教
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   
无界线程池submit方法提交两个个任务,代码如下(代码都是在同一个继承Runnable类中):
 Callable<Boolean> leftCallable = new Callable<Boolean>() {
 @Override
 public Boolean call() throws Exception {
 return WaterPostService.validateWater(leftData, leftPostWater);
 }

 };
 Callable<Boolean> rightCallable = new Callable<Boolean>() {
 @Override
 public Boolean call() throws Exception {
 return WaterPostService
 .validateWater(rightData, rightPostWater);
 }
 };
Future<Boolean> leftFuture = AlosinContext.threadPoolService.submit(leftCallable);
Future<Boolean> rightFuture=AlosinContext.threadPoolService.submit(rightCallable); 

2.然后两个任务传入的参数是全局的变量,通过提交的任务改变传入参数某些属性值

3.最后再将参数传给以下代码,作最后处理
boolean leftPostResut = WaterPostService.postWater(leftData, leftPostWater);
boolean rightPostResult = WaterPostService.postWater(rightData, rightPostWater); 


现在的问题是:1.无界线程池的submit方法是立即执行吗?
                       2.传入的参数没有改变属性值,但是看日志文件提交的任务是执行了的,但是leftPostWater这个变量的属性却没有改变 
举报
ALOSIN
发帖于6年前 5回/6K+阅

以下是问题补充:

  • @ALOSIN :这个问题困扰我很久了,大家帮帮忙啦,呵呵 (6年前)
  • @ALOSIN :哦 补充一点,这个出现这个情况的几率很小 (6年前)
共有5个答案 最后回答: 6年前
我大概明白了你的流程, validateWater应该是修改了两个参数状态,然后 postWater读取参数的状态做出判断。 validateWater和 postWater是在不同线程中执行的。但是没有足够的同步保证 validateWater所做的修改一定能被 postWater看到,即 postWater看到的可能是过期值。

1.cachedThreadPool是submit后立即使用现有空闲线程或启动一个新线程执行。

2.提交后主线程没有被阻塞,两个任务线程和主线程是并行的,主线程不会等待任务线程结束。所以变量里不是你的期望值(我猜测你的期望值应该是validateWater后再“串行”执行postWater的结果),此时任务线程状态有多种可能的情况。

引用来自“canghailan”的答案

1.cachedThreadPool是submit后立即使用现有空闲线程或启动一个新线程执行。

2.提交后主线程没有被阻塞,两个任务线程和主线程是并行的,主线程不会等待任务线程结束。所以变量里不是你的期望值(我猜测你的期望值应该是validateWater后再“串行”执行postWater的结果),此时任务线程状态有多种可能的情况。

第一点得到回复后,第二点就更奇怪了,就像你说的,我的感觉也是任务线程没执行完,就开始后面的postWater了,但是我提交任务后是用Future.get()来阻塞获取结果的,只有获取结果后才往下面执行
--- 共有 8 条评论 ---
ALOSIN呵呵,可以啊,粉你一下 6年前 回复
canghailan回复 @蒋伟 : 呵呵,一起探讨,最近也是在看这方面的书。如果想确认的话可以加上同步看看。 6年前 回复
ALOSIN谢谢,感觉有点像可见性问题啊,呵呵,感谢 6年前 回复
canghailan回复 @蒋伟 : 不是,你这儿也没用到ThreadLocal。简单说就是不同线程间,如果没有合适的同步机制,A线程所做的修改可能B线程看不到,的确是个很难理解的东西。 6年前 回复
ALOSIN有没有可能是ThreadLocal这种问题 6年前 回复

引用来自“canghailan”的答案

ThreadPoolExecutor和Future的API文档里有说明和基本用法。
Future.get()不是一直阻塞,直到获取结果完成吗,而且我获取的结果是boolean类型的,只有为true时才往下面执行,既然为true,说明是一直等到任务线程完成的,那么传入的变量就应该是改变了的,所以问题很诡异啊
--- 共有 1 条评论 ---
canghailan恩,才看到。这个是解决了有序性。 6年前 回复
顶部