# Thread及Runnable執行緒

## 多開一個執行緒-extends Thread

若只要多開一個執行緒，繼承Thread就可以了。要執行的功能放在run()方法內。

```java
public class Horse extends Thread {
    @Override
    public void run(){
        ...
    }
}
```

要使用此Thread物件，就new出實例來

```java
Horse horse = new Horse();
horse.start();
```

## 多執行緒-implements Runnable

若需要多個執行緒，就實作Runnable介面。同樣的，執行功能放在run()方法。

```java
public class HorseRunnable implements Runnable {
    @Override
    public void run(){
        ...
    }
}
```

若要使用Runnable物件，需要先new出Runnable物件，再用此物件產生Thread物件。

```java
HorseRunnable horseRunnable = new HorseRunnable();
Thread thr = new Thread(horseRunnable);
thr.start();
```

## 三P馬的賽馬範例

目前有三匹馬，分別是三個執行緒，而main執行緒主要負責計算賽馬名次。

```java
public class Horse extends Thread {
    @Override
    public void run(){
        try{
            //延遲2秒
            sleep(2000);
            //getName()可以取得執行緒名稱
            System.out.println(getName() + "到達");
        }catch(InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
```

開個賽馬場囉～

```java
public class Racing{
    Horse h1 = new Horse();
    Horse h2 = new Horse();
    Horse h3 = new Horse();
    
    h1.setName("h1");
    h2.setName("h2");
    h3.setName("h3");
    
    h1.start();
    h2.start();
    h3.start();
}
```

最後發現main執行緒會比其他三匹馬更早結束，為了讓main(裁判)等待三匹馬完成，使用join()方法來等待結果。

```java
public class Racing{
    Horse h1 = new Horse();
    Horse h2 = new Horse();
    Horse h3 = new Horse();
    
    h1.setName("h1");
    h2.setName("h2");
    h3.setName("h3");
    
    h1.start();
    h2.start();
    h3.start();
    
    try{
        h1.join();
        h2.join();
        h3.join();
    }
    catch(InterruptedException e)
    {
        e.printStackTrace();
    }
    System.out.println("執行緒結束");
}
```

如此一來便會等待馬匹跑完以後，main執行緒才會結束。

## 賽馬排名

新增紀錄排名的集合

```java
public class Racing{
    //增加紀錄排名的集合
    List<RankHorse> rank = new ArrayList();
    Horse h1 = new Horse();
    Horse h2 = new Horse();
    Horse h3 = new Horse();
    
    h1.setName("h1");
    h2.setName("h2");
    h3.setName("h3");
    
    h1.start();
    h2.start();
    h3.start();
    
    try{
        h1.join();
        h2.join();
        h3.join();
    }
    catch(InterruptedException e)
    {
        e.printStackTrace();
    }
    System.out.println("執行緒結束");
    System.out.println(rank);
}
```

```java
public class RankHorse extends Thread {
    private List<RankHorse> rank;
    
    //傳入排名集合
    public RankHorse(List<RankHorse> rank){
        this.rank = rank;
    }
    
    @Override
    public void run(){
        try{
            //延遲2秒
            sleep(2000);
            //getName()可以取得執行緒名稱
            System.out.println(getName() + "到達");
            
            //加入集合
            rank.add(this);
        }catch(InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}
```

## yield()和sleep()會暫停目前工作，進入等待隊列(Queue)

## 資源鎖定synchronized

限制同一時間只能有一個執行緒執行該方法，可以透過同步方法或同步區塊達成。

同步方法：

```java
public class Wizard extends Thread{
    public void run(){
       thunder(); 
    }
    
    //規定一次只能有一個人使用打雷
    public synchronized void thunder(){
       System.out.println("THUNDER!!");
    }
}
```

```java
Wizard wiz1 = new Wizard();
Wizard wiz2 = new Wizard();
wiz1.start();
wiz2.start();
```

同步區塊：

```java
public class Wizard extends Thread{
    public void run(){
       synchronized(this){
          thunder(); 
       }
    }
    
    
    //規定一次只能有一個人使用打雷
    public void thunder(){
       System.out.println("THUNDER!!");
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yoyo840821.gitbook.io/android-learning/master.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
