Java并发编程核心方法与框架-Future和Callable的使用

Callable接口与Runnable接口对比的主要优点是Callable接口可以通过Future获取返回值。但是Future接口调用get()方法取得结果时是阻塞的,如果调用Future对象的get()方法时任务尚未执行完,则调用get()方法时一直阻塞到此任务完成。如果前面的任务耗时很多,则后面的任务调用get()方法就呈阻塞状态,大大影响运行效率。主线程不能保证首先获得的是最先完成任务的返回值,这是Future的缺点。

public class MyCallable implements Callable<String> {
	private int age;
	
	public MyCallable(int age) {
		super();
		this.age = age;
	}
	@Override
	public String call() throws Exception {
		TimeUnit.SECONDS.sleep(8);
		return "返回值 年龄是:" + age;
	}
	
	public static void main(String[] args) {
		MyCallable myCallable = new MyCallable(22);
		int corePoolSize = 2;
		int maximumPoolSize = 3;
		int keepAliveTime = 5;
		TimeUnit unit = TimeUnit.SECONDS;
		LinkedBlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<Runnable>();
		ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
		Future<String> future = threadPoolExecutor.submit(myCallable);
		try {
			System.out.println(System.currentTimeMillis());
			String string = future.get();
			System.out.println(string);
			System.out.println(System.currentTimeMillis());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

打印结果如下:

1470904027660
返回值 年龄是:22
1470904035663

从打印结果看,可见get()方法具有阻塞的特性。

方法submit()不仅可以传入Callable对象,还可以传入Runnable对象,submit()方法支持有返回值和无返回值。

public class Run {
	public static void main(String[] args) {
		try {
			Runnable runnable = new Runnable() {
				
				@Override
				public void run() {
					System.out.println("打印的信息");
				}
			};
			ExecutorService executorService = Executors.newCachedThreadPool();
			Future future = executorService.submit(runnable);
			System.out.println(future.get() + " " + future.isDone());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

打印结果如下:

打印的信息
null true

方法isDone()无阻塞特性。


使用ExecutorService接口中的方法submit(Runnable, T result)
public class User {
	private String username;
	private String password;
    //省略getter setter
}

public class MyRunnable implements Runnable {
	private User user;
	public MyRunnable(User user) {
		super();
		this.user = user;
	}
	@Override
	public void run() {
		try {
			TimeUnit.SECONDS.sleep(2);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		user.setUsername("admin");
		user.setPassword("123456");
	}
}

public class Main {
	FutureTask task;
	public static void main(String[] args) {
		try {
			User user = new User();
			MyRunnable myRunnable = new MyRunnable(user);
			int corePoolSize = 10;
			int maximumPoolSize = 10;
			int keepAliveTime = 10;
			TimeUnit unit = TimeUnit.SECONDS;
			LinkedBlockingDeque<Runnable> workQueue = new LinkedBlockingDeque<>();
			ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
			Future<User> future = executor.submit(myRunnable, user);
			System.out.println(System.currentTimeMillis());
			System.out.println(user.getUsername() + "-" + user.getPassword());
			user = future.get();
			System.out.println(user.getUsername() + "-" + user.getPassword());
			System.out.println(System.currentTimeMillis());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

控制台打印结果如下:

1470908214853
null-null
admin-123456
1470908216855
原文地址:https://www.cnblogs.com/umgsai/p/5671657.html