在Java语言中,从JDK1.0开始就有多线程,在多线程的实现上面有多种形式,本例以实现Callable接口。

java.lang.Runnable接口中run()方法是没有返回值的,如果需要返回值怎么办?这时候实现Callable接口,在call()方法就有返回值的。

1
public V call();

Callable接口类似于Runnable,因为它们都是为其实例可能被另一个线程执行的类设计的。 然而,Runnable不返回结果,也不能抛出被检查的异常。

实现Callable接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyCallable implements Callable<String>{

private String threadName ;

public MyCallable(String threadName) {
this.threadName = threadName;
}

public String call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println( threadName + " - " + i);
}

return "excute success.";
}
}

启动多线程

在启动实现Callable接口的多线程的时候并没有start()方法,在FutureTask类中有可以接受的构造方法:

1
public FutureTask(Callable<V> callable);

因为FutureTask有实现RunnableFuture接口,而RunnableFuture又继承Runnable接口,这样在Thread能接受FutureTask

1
public class FutureTask<V> extends Object implements RunnableFuture<V>
1
public interface RunnableFuture<V> extends Runnable, Future<V>

完整实例:
File: CallableDemo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.devnp;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
* Created by duliu on 26/8/2017.
*/
class MyCallable implements Callable<String>{

private String threadName ;

public MyCallable(String threadName) {
this.threadName = threadName;
}

public String call() throws Exception {
for (int i = 0; i < 10; i++) {
System.out.println( threadName + " - " + i);
}

return "execute success.";
}
}

public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable myCallable1 = new MyCallable("Thread one");
MyCallable myCallable2 = new MyCallable("Thread two");

FutureTask<String> futureTask1 = new FutureTask<String>(myCallable1);
FutureTask<String> futureTask2 = new FutureTask<String>(myCallable2);

new Thread(futureTask1).start();
new Thread(futureTask2).start();

System.out.println(futureTask1.get());
System.out.println(futureTask2.get());
}
}