# Thread
(Thread中文可以叫做: 執行續/線程)
目前上面寫過的程式, 都是單執行續, 意思是這個process同時只會做一件事
但其實可以同時有多個Thread, 同時(並發)執行。
Thread有一些static方法,
```
Thread currentThread(); 取得當前執行的thread
void sleep(long); 當前thread休眠一段時間(毫秒)
```
範例:
```java=
public class Main {
public static void main(String[] args) {
Thread t = Thread.currentThread();
System.out.println(t.getName()); //main
Thread.sleep(1000);
System.out.println(t.isAlive()); //true
}
}
```
假設我們想要在**背景** 輸出1~5, 每次輸出delay 1秒
用這種正常寫法是沒辦法達成的, 永遠會先一行一行慢慢執行
```java=
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
Thread.sleep(1000);
System.out.println(i);
}
System.out.println("Hello World!");
}
```
## 創造Thread
執行Thread的時候, 是呼叫Thread裡面的run()方法
Thread某幾段原始碼如下:
```java=
public class Thread implements Runnable {
private Runnable target;
//a few hundred lines
public Thread(Runnable target) { //constructor
//constructor contents...
}
//a few hundred lines
@Override
public void run() {
if (target != null) {
target.run();
}
}
//a few hundred lines
}
```
這時候有兩種方法可以創造有run()值行的thread
### 1. Override Thread#run()
standard override
```java=
class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
Thread.sleep(1000);
System.out.println(i);
}
}
}
// ---------- main ----------
MyThread t = new MyThread();
```
anonymous
```java=
// ---------- main ----------
Thread t = new Thread() {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
Thread.sleep(1000);
System.out.println(i);
}
}
};
```
### 2. Create target Runnable
```java=
// ---------- runnable implementation ----------
class YourRunnable implements Runnable {
@Override
public void run() {
//...
}
}
// ---------- main ----------
Thread t = new Thread(new YourRunnable());
```
anonymous
```java=
Runnable r = new Runnable({
@Override
public void run() {
//...
}
};
// ---------- main ----------
Thread t = new Thread(r);
```
lambda:
```java=
Runnable r = () -> {
@Override
public void run() {
//...
}
};
// ---------- main ----------
Thread t = new Thread(r);
```
lambda, 但直接放入參數中:
```java=
// ---------- main ----------
Thread t = new Thread(() -> {
@Override
public void run() {
//...
}
});
```
## 執行thread
```java=
Thread#start();
```
```java=
Thread thread = new Thread(r);
thread.start(); //啟動Thread
System.out.println(thread.isActive()); //true, 因為此時thread確實在背景執行
/*
true
1
2
3
4
5
*/
```
**注意, 啟動thread是呼叫```start()```,不是```run()```**
run()純粹是執行Runnable裡面的```run()```, 會直接把main thread sleep掉!
```java=
Thread thread = new Thread(r);
thread.run(); //直接在main thread 呼叫runnable, 並沒有啟動thread
System.out.println(thread.isAlive()); //false, 因為thread從未被啟動
/*
1
2
3
4
5
false
*/
```
## 終止thread
```java=
Thread#interrupt();
```
假設我們想要在Runnable裡面直接終止Thread:
```java=
@Override
public void run() {
try {
for (int i = 1; i <= 5; i++) {
Thread.sleep(1000);
System.out.println(i);
if (i == 3) {
return; //直接結束run()
}
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
};
//>
```
# Timer
Java Timer能讓你把task放進Timer的TaskQueue, 並且可以選擇:
1. ```schedule(task,delay)```延遲delay ms後開始,
2. ```schedule(task,delay,period)```延遲delay ms後開始, 並且每period ms執行一次
除了```schedule```, 還有一個叫做```scheduleAtFixedRate```
```schedule```會因為被系統其他因素(如GC)延遲 而延遲下一次任務
```scheduleAtFixedRate```如果被延遲, 他會把未執行的任務做完
1000ms後, 執行一次run()
```java==
Timer t = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("hello");
}
};
t.schedule(task,1000);
```
2000ms後, 每1000ms執行一次run()
```java==
Timer t = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("hello");
}
};
t.schedule(task,2000,1000);
```