Executors.newCachedThreadPool() 无界线程池诡异问题,大家赐教

ALOSIN 发布于 2012/04/23 20:13
阅读 6K+
收藏 0
无界线程池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:这个问题困扰我很久了,大家帮帮忙啦,呵呵 (2012/04/23 20:17)
@ALOSIN:哦 补充一点,这个出现这个情况的几率很小 (2012/04/23 20:22)
加载中
0
canghailan
canghailan
我大概明白了你的流程, validateWater应该是修改了两个参数状态,然后 postWater读取参数的状态做出判断。 validateWater和 postWater是在不同线程中执行的。但是没有足够的同步保证 validateWater所做的修改一定能被 postWater看到,即 postWater看到的可能是过期值。
0
canghailan
canghailan

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

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

0
ALOSIN
ALOSIN

引用来自“canghailan”的答案

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

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

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

引用来自“canghailan”的答案

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