---
# System prepended metadata

title: 多執行緒的範例
tags: [ocpjp]

---

# 多執行緒的範例
```java=
class Caller implements Callable<String> {
	String str;
	public Caller (String s) {
		this.str=s;
	}
	@Override
	public String call() throws Exception {
		return str.concat (" Caller");
	}
	
}
class Runner implements Runnable {
	String str;
	public Runner (String s) {
		this.str=s;
	}
	@Override
	public void run() {
		System.out.println (str.concat (" Runner"));
	}
	
}
public class Test {
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		ExecutorService es = Executors.newFixedThreadPool(2);
		Future f1 = es.submit (new Caller ("Call"));
		Future f2 = es.submit (new Runner ("Run"));
		String str1 = (String) f1.get();
		String str2 = (String) f2.get();//line n1
		System.out.println(str1+ ":" + str2);
	}

}
```

**Console: 會印出下面結果，並且程式不會中斷**
```Console=
Run Runner
Call Caller:null
```

---
[參考網頁](https://magiclen.org/ocpjp-executorservice/)

:::info
程式第25行，會建立最多可以擁有兩個執行緒的ExecutorService。

程式第26行，會建立Caller物件，並使用新的執行緒去執行Caller物件的call方法。

程式第27行，會建立Runnable物件，並使用新的執行緒去執行Runnable物件的run方法。

程式第28行，會等待呼叫Caller物件的call方法的執行緒是否已經執行完畢，接著回傳call方法的回傳值。

程式第29行，會等待呼叫Runnable物件的run方法的執行緒是否已經執行完畢，接著回傳null。

在程式第27行至29行之間，某條ExecutorService的執行緒會執行到Runnable物件的run方法內的第19行，輸出「Run Runner」。

程式第30行，輸出「Call Caller : null」。
:::

###### tags: `ocpjp`