# 06-控制线程

参考了《疯狂java讲义》的提法，将如下内容归为控制线程。

## join

主线程join一个线程，那么主线程会阻塞直到join进来的线程执行完，主线程继续执行， join如果带超时时间的话，那么如果超时的话主线程也会不再等join进去的线程而继续执行.

join实际就是判断join进来的线程存活状态，如果活着就调用wait(0),如果带超时时间了的话，wait里边的时间会算出来

```java
while (isAlive()) {
    wait(0);
}
```

### API

* public final void join() throws InterruptedException
* public final synchronized void join(long millis, int nanos)
* public final synchronized void join(long millis)

### 例子

```java
public class Demo_02_06_1_join extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(this.getName() + "  " + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Demo_02_06_1_join joinThread = new Demo_02_06_1_join();
        for (int i = 0; i < 100; i++) {

            if (i == 10) {
                joinThread.start();
                joinThread.join();
            }
            // 打到9就停了，然后执行joinThread这里里边的代码，完事继续从10打
            System.out.println(Thread.currentThread().getName()+"  "+i);
        }
    }
}
```

## sleep

睡觉方法，使得线程暂停一段时间，进入阻塞状态。

### API

* public static native void sleep(long millis) throws InterruptedException
* public static void sleep(long millis, int nanos) throws InterruptedException

### 示例

```java
public class Demo_02_06_2_sleep extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            if (i == 5) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
            // 输出到4停止， 5秒后继续
            System.out.println(this.getName() + "  " + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Demo_02_06_2_sleep sleepThread = new Demo_02_06_2_sleep();
        sleepThread.start();
    }
}
```

## yield

也是让线程暂停一下，但是是进入就绪状态，让系统重新开始一次新的调度过程

```
Thread.yield()
```

## 中断

Java中断机制是一种协作机制，也就是说通过中断并不能直接终止另一个线程，而需要被中断的线程自己处理中断。

前面有一些方法声明了InterruptedException， 这意味者他们可以被中断，中断后把异常抛给调用方，让调用方自己处理.

被中断的线程可以自已处理中断，也可以不处理或者抛出去。

```java
public class Demo_02_06_3_interrupt extends Thread {

    static class MyCallable implements Callable {
        @Override
        public Integer call() throws InterruptedException {
            for (int i = 0; i < 5000; i++) {
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("3333");
                    throw new InterruptedException("中断我干嘛，关注 微信号 大雄和你一起学编程 呀");
                }
            }
            return 0;
        }
    }
    public static void main(String[] args) throws InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask<>(new MyCallable());
        Thread thread = new Thread(futureTask);
        thread.start();
        for (int i = 0; i < 100; i++) {
            if (i == 3) {
                thread.interrupt();
            }
        }
        try {
            futureTask.get();
        } catch (ExecutionException e) {
            // 这里会捕获到异常
            e.printStackTrace();
        }

    }
}
```


---

# 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://yibingxiong.gitbook.io/java-concurrent-programming-art-mini/di-02-zhang-bing-fa-bian-cheng-ji-chu/06-kong-zhi-xian-cheng.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.
