Callable 和 Runnable 的使用方法大同小異, 區別在於:
1、Callable 使用 call() 方法, Runnable 使用 run() 方法
2、call() 有傳回值, 而 run()方法沒有傳回值。
3、call() 可以拋出受檢查的異常,比如ClassNotFoundException, 而run()不能拋出受檢查的異常。
Callable樣本如下:
class CallableImpl implements Callable {private int age;public CallableImpl(int age) {this.age = age;}// 具體邏輯在這裡實現,並有一個傳回值public Object call() throws Exception {Thread.currentThread().sleep(new Random().nextInt(1000));String ss="";if (age < 0) {ss="age = " + age + ", 輸入年齡有誤";} else if (age < 20) {ss="age = " + age + ", 你好,年輕人";} else if (age < 40) {ss= "age = " + age + ", 你好,中年人";} else {ss= "age = " + age + ", 你好,老年人";}System.out.println(ss);return ss;}}public class CallableTest {public static void main(String[] args) throws InterruptedException, ExecutionException {// 建立一個線程池ExecutorService exc = Executors.newFixedThreadPool(3);// 存放返回的結果List<Future<String>> futures = new ArrayList<Future<String>>();for (int i = -10; i < 50; i += 3) {CallableImpl call = new CallableImpl(i);// 執行callable的call方法,並有傳回值Future<String> future = exc.submit(call);futures.add(future);}System.out.println("等待結果:");for (Future<String> future : futures) { // 這裡調用get()方法會阻塞當前線程,直到得到返回結果 System.out.println("----------- "+future.get()); // if (future.isDone()) { // System.out.println(future.get()); // } else { // System.out.println("Future result is not yet complete"); // } }System.out.println("結束...");//Thread.currentThread().sleep(1000*30);exc.shutdown();}}
結果:
等待結果:age = -10, 輸入年齡有誤----------- age = -10, 輸入年齡有誤age = -4, 輸入年齡有誤age = -1, 輸入年齡有誤age = 2, 你好,年輕人age = -7, 輸入年齡有誤----------- age = -7, 輸入年齡有誤----------- age = -4, 輸入年齡有誤----------- age = -1, 輸入年齡有誤----------- age = 2, 你好,年輕人age = 11, 你好,年輕人age = 5, 你好,年輕人----------- age = 5, 你好,年輕人age = 8, 你好,年輕人----------- age = 8, 你好,年輕人----------- age = 11, 你好,年輕人age = 17, 你好,年輕人age = 14, 你好,年輕人----------- age = 14, 你好,年輕人----------- age = 17, 你好,年輕人age = 26, 你好,中年人age = 23, 你好,中年人age = 20, 你好,中年人----------- age = 20, 你好,中年人----------- age = 23, 你好,中年人----------- age = 26, 你好,中年人age = 35, 你好,中年人age = 32, 你好,中年人age = 41, 你好,老年人age = 29, 你好,中年人----------- age = 29, 你好,中年人----------- age = 32, 你好,中年人----------- age = 35, 你好,中年人age = 38, 你好,中年人----------- age = 38, 你好,中年人----------- age = 41, 你好,老年人age = 44, 你好,老年人----------- age = 44, 你好,老年人age = 47, 你好,老年人----------- age = 47, 你好,老年人結束...
Runnable樣本:
public class LiftOff implements Runnable {protected int countDown = 10;private static int taskCount = 0;private final int id = taskCount++;public LiftOff() {}public LiftOff(int countDown) {this.countDown = countDown;}public String status() {return "#" + id + "(" + (countDown > 0 ? countDown : "LiftOff! ") + ")";}@Overridepublic void run() {while (countDown-- > 0) {System.out.print(status());Thread.yield();}System.out.println();}public static void main(String[] args) {ExecutorService exec = Executors.newFixedThreadPool(1);for (int i = 0; i < 5; i++) {exec.execute(new LiftOff());}exec.shutdown();}}
注意ExecutorService 在Callable中使用的是submit(), 在Runnable中使用的是 execute()。