多线程执行顺序问题,请教

木鱼121 2014-11-04 09:11:36
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


public class TestExecutor{
public static void main(String[] args) throws Exception{
ExecutorService es = Executors.newCachedThreadPool();//创建线程池对象
List<Future<String>> result =new ArrayList<Future<String>>();//放结果用的集合
for(int i=0;i<3;i++){
Future<String> f=es.submit(new MyCall(i));//线程执行完成以后可以通过引用获取返回值
System.out.println("Future<String>... ..."+i);
result.add(f);
}
for(Future<String> f:result){
System.err.println("返回值:"+f.get());//输出返回的值
}
System.err.println("完成....");
}
}

//声明一个类,可以被调用,类似于线程,但它可以拥有返回值
class MyCall implements Callable<String>{
private int seq;
public MyCall(int seq){
this.seq=seq;
}
//抛出异常并可以拥有返回值
public String call() throws Exception {
System.err.println("执行"+seq+","+Thread.currentThread().getName());
Thread.sleep(3000);
System.err.println("Weak up "+seq);
return "完成"+seq;//这是返回值
}
}

输出内容:
Future<String>... ...0
执行0,pool-1-thread-1
执行1,pool-1-thread-2
执行2,pool-1-thread-3
Future<String>... ...1
Future<String>... ...2
Weak up 2
Weak up 1
Weak up 0
返回值:完成0
返回值:完成1
返回值:完成2
完成....

问题来了:问什么输出 执行2,pool-1-thread-3 为什么会出现Future<String>... ...1之前先执行呢??
我的理解是,即便是在多线程中,for循环,也没有理由执行两次Future<String> f=es.submit(new MyCall(i)); 才执行一次System.out.println("Future<String>... ..."+i);


请高手指教,如有我描述不清地方,请大家说明,我后续补充描述。
...全文
75 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
木鱼121 2014-11-04
  • 打赏
  • 举报
回复
懂了 谢谢 原来问题出在缓存流上面了。
Mr_JieLQ 2014-11-04
  • 打赏
  • 举报
回复
你很细心,你说的顺序是对的,但是你犯了一个错误,不应该在一个程序里即使用 System.out.println输出语句,又使用 System.err.println语句,前者带有缓存,所以,你同时使用两种输出,顺序就不能保证,只用一种输出流你的例子中的顺序就不会出现,如下

package test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class TestExecutor {
	public static void main(String[] args) throws Exception {
		ExecutorService es = Executors.newCachedThreadPool();// 创建线程池对象
		List<Future<String>> result = new ArrayList<Future<String>>();// 放结果用的集合
		for (int i = 0; i < 3; i++) {
			Future<String> f = es.submit(new MyCall(i));// 线程执行完成以后可以通过引用获取返回值
			System.out.println("Future<String>... ..." + i);
			result.add(f);
		}
		for (Future<String> f : result) {
			System.out.println("返回值:" + f.get());// 输出返回的值
		}
		System.out.println("完成....");
	}
}

class MyCall implements Callable<String> {
	private int seq;

	public MyCall(int seq) {
		this.seq = seq;
	}

	// 抛出异常并可以拥有返回值
	public String call() throws Exception {
		System.out.println("执行" + seq + "," + Thread.currentThread().getName());
		Thread.sleep(3000);
		System.out.println("Weak up " + seq);
		return "完成" + seq;// 这是返回值
	}
}

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧