如果是java5的话,那么Java5新增了Callable接口获得线程的返回值,用法如下
package com.ronniewang
import java.util.concurrent.Callable
import java.util.concurrent.ExecutionException
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.Future
public class GetReturnValueFromCallable {
private static final int SLEEP_MILLS = 3000
private static final int SECOND_MILLS = 1000
private static int sleepSeconds = SLEEP_MILLS / SECOND_MILLS
ExecutorService executorService = Executors.newCachedThreadPool()
/**
* 在创建多线程程序的时候,我们常实现Runnable接口,Runnable没有返回值,要想获得返回值,Java5提供了一个新的接口Callable
*/
public static void main(String[] args) {
new GetReturnValueFromCallable().testCallable()
}
private void testCallable() {
/**
* Callable需要实现的是call()方法,而不是run()方法,返回值的类型有Callable的类型参数指定,
* Callable只能由ExecutorService.submit() 执行,正常结束后将返回一个future对象
*/
Future<String> future = executorService.submit(new Callable<String>() {
public String call() throws Exception {
Thread.sleep(SLEEP_MILLS)
return "I from callable"
}
})
while (true) {
/**
* 获得future对象之前可以使用isDone()方法检测future是否完成,完成后可以调用get()方法获得future的值,
* 如果直接调用get()方法,get()方法将阻塞值线程结束
*/
if (future.isDone()) {
try {
System.out.println(future.get())
break
} catch (InterruptedException e) {
// ignored
} catch (ExecutionException e) {
// ignored
}
}
else {
try {
System.out.println("after " + sleepSeconds-- + " seconds, we will get future")
Thread.sleep(SECOND_MILLS)
} catch (InterruptedException e) {
// ignored
}
}
}
}
}
package com.ronniewang
import java.util.concurrent.Callable
import java.util.concurrent.ExecutionException
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.Future
public class GetReturnValueFromCallable {
private static final int SLEEP_MILLS = 3000
private static final int SECOND_MILLS = 1000
private static int sleepSeconds = SLEEP_MILLS / SECOND_MILLS
ExecutorService executorService = Executors.newCachedThreadPool()
/**
* 在创建多线程程序的时候,我们常实现Runnable接口,Runnable没有返回值,要想获得返回值,Java5提供了一个新的接口Callable
*/
public static void main(String[] args) {
new GetReturnValueFromCallable().testCallable()
}
private void testCallable() {
/**
* Callable需要实现的是call()方法,而不是run()方法,返回值的类型有Callable的类型参数指定,
* Callable只能由ExecutorService.submit() 执行,正常结束后将返回一个future对象
*/
Future<String> future = executorService.submit(new Callable<String>() {
public String call() throws Exception {
Thread.sleep(SLEEP_MILLS)
return "I from callable"
}
})
while (true) {
/**
* 获得future对象之前可以使用isDone()方法检测future是否完成,完成后可以调用get()方法获得future的值,
* 如果直接调用get()方法,get()方法将阻塞值线程结束
*/
if (future.isDone()) {
try {
System.out.println(future.get())
break
} catch (InterruptedException e) {
// ignored
} catch (ExecutionException e) {
// ignored
}
}
else {
try {
System.out.println("after " + sleepSeconds-- + " seconds, we will get future")
Thread.sleep(SECOND_MILLS)
} catch (InterruptedException e) {
// ignored
}
}
}
}
}
输出结果:
after 3 seconds, we will get future
after 2 seconds, we will get future
after 1 seconds, we will get future
I from callable
可以通过实现Callable接口创建一个有返回值的线程,代码如下:
import java.util.concurrent.*public class MyThread implements Callable<Integer> {
private int count
public MyThread(int count) {
this.count = count
}
@Override
public Integer call() throws Exception {
// 此处是线程要处理的业务代码,此处实现的是对count变量加1的操作
count += 1
Thread.sleep(1000)
return count
}
public static void main(String[] args) {
// 创建线程实例
MyThread myThread = new MyThread(1)
// 创建一个大小为10的线程池
ExecutorService executor = Executors.newFixedThreadPool(10)
// 将线程提交到线程池执行
Future<Integer> future = executor.submit(myThread)
try {
// 调用get方法获取线程执行结果,在线程执行完成前该方法会一直阻塞
Integer result = future.get()
System.out.println(result)
} catch (InterruptedException e) {
e.printStackTrace()
} catch (ExecutionException e) {
e.printStackTrace()
}
// try {
// // 这种写法可以设置线程执行的超时时间,当线程超过指定的时间还未执行完成时会抛出TimeoutException异常
// // 示例中表示线程超过1000毫秒还没执行完就会抛出超时异常
// Integer result = future.get(1000, TimeUnit.MILLISECONDS)
// System.out.println(result)
// } catch (InterruptedException e) {
// e.printStackTrace()
// } catch (ExecutionException e) {
// e.printStackTrace()
// } catch (TimeoutException e) {
// e.printStackTrace()
// }
}
}