简介
这两个都是接口,在Java多线程中用得很多。主要区别有:
Runnable Interface | Callable Interface | |
---|---|---|
类包 | java.lang.Runnable,JDK 1.0就有 | java.util.concurrent.Callable, JDK 1.5引入 |
方法 | public abstract void run(); |
V call() throws Exception; |
异常 | 不可以抛异常; | 可以抛异常; |
返回值 | 不可以返回值; | 可以返回任意对象;支持泛型。 |
代码定义
Runnable
:
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
Java
Callable
:
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
Java
如何使用
Runnable
需要实现run()
方法:
class PkslowRunnable implements Runnable {
private final String name;
PkslowRunnable(String name) {
this.name = name;
}
@Override
public void run() {
System.out.println(name + " is running");
try {
Thread.sleep(1000);
System.out.println(name + " is completed");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Java
我们可以使用 ExecutorService
来提交Runnable任务:
private static void runnable() {
ExecutorService executorService = Executors.newFixedThreadPool(4);
executorService.submit(new PkslowRunnable("pkslow.r1"));
executorService.submit(new PkslowRunnable("pkslow.r2"));
executorService.submit(new PkslowRunnable("pkslow.r3"));
executorService.submit(new PkslowRunnable("pkslow.r4"));
executorService.submit(new PkslowRunnable("pkslow.r5"));
executorService.submit(new PkslowRunnable("pkslow.r6"));
executorService.submit(new PkslowRunnable("pkslow.r7"));
executorService.submit(new PkslowRunnable("pkslow.r8"));
executorService.submit(new PkslowRunnable("pkslow.r9"));
executorService.submit(new PkslowRunnable("pkslow.r10"));
awaitTerminationAfterShutdown(executorService);
}
Java
输出:
pkslow.r4 is running
pkslow.r2 is running
pkslow.r3 is running
pkslow.r1 is running
pkslow.r2 is completed
pkslow.r4 is completed
pkslow.r1 is completed
pkslow.r3 is completed
pkslow.r5 is running
pkslow.r6 is running
pkslow.r7 is running
pkslow.r8 is running
pkslow.r5 is completed
pkslow.r7 is completed
pkslow.r6 is completed
pkslow.r8 is completed
pkslow.r10 is running
pkslow.r9 is running
pkslow.r10 is completed
pkslow.r9 is completed
Bash
Callable
需要实现call()
方法:
class PkslowCallable implements Callable<Integer> {
private final String name;
PkslowCallable(String name) {
this.name = name;
}
@Override
public Integer call() throws Exception {
System.out.println(name + " is running");
try {
Thread.sleep(1000);
System.out.println(name + " is completed");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return (new Random().nextInt()) % 100;
}
}
Java
这里我们直接返回一个随机结果。
同样,我们也是可以使用 ExecutorService
来提交 Callable
任务:
private static void callable() {
ExecutorService executorService = Executors.newFixedThreadPool(4);
List<Future<Integer>> futures = new ArrayList<>();
futures.add(executorService.submit(new PkslowCallable("pkslow.c1")));
futures.add(executorService.submit(new PkslowCallable("pkslow.c2")));
futures.add(executorService.submit(new PkslowCallable("pkslow.c3")));
futures.add(executorService.submit(new PkslowCallable("pkslow.c4")));
futures.add(executorService.submit(new PkslowCallable("pkslow.c5")));
futures.add(executorService.submit(new PkslowCallable("pkslow.c6")));
futures.add(executorService.submit(new PkslowCallable("pkslow.c7")));
futures.add(executorService.submit(new PkslowCallable("pkslow.c8")));
futures.add(executorService.submit(new PkslowCallable("pkslow.c9")));
futures.add(executorService.submit(new PkslowCallable("pkslow.c10")));
futures.forEach(ft -> {
try {
System.out.println("Result from Future: " + ft.get());
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
});
awaitTerminationAfterShutdown(executorService);
}
Java
通过调用 Future.get()
,我们可以拿到对应的结果。
输出:
pkslow.c1 is running
pkslow.c3 is running
pkslow.c2 is running
pkslow.c4 is running
pkslow.c2 is completed
pkslow.c1 is completed
pkslow.c3 is completed
pkslow.c4 is completed
pkslow.c5 is running
pkslow.c7 is running
pkslow.c6 is running
pkslow.c8 is running
Result from Future: 62
Result from Future: 3
Result from Future: -1
Result from Future: 38
pkslow.c7 is completed
pkslow.c6 is completed
pkslow.c8 is completed
pkslow.c5 is completed
pkslow.c10 is running
pkslow.c9 is running
Result from Future: 19
Result from Future: -42
Result from Future: 73
Result from Future: 84
pkslow.c10 is completed
pkslow.c9 is completed
Result from Future: -32
Result from Future: -48
Bash
代码
代码请查看GitHub: https://github.com/LarryDpk/pkslow-samples