# Thread 多线程基础

![](https://github.com/chesterzhang/intro_Java/blob/zhc_dev/picture/thread/thread.png?raw=true)

Java 多线程的创建有两种形式:

1. 一个类继承 Thread，重写 run 方法，再实例化这个类。
2. 一个类实现Runnable 接口，重写 run 方法，在实例化这个类(更加常用)。

实际应用中第二种方法更常见, 因为Java不支持多继承, 通过实现接口更加方便。

## 方法1实现多**线程**:

我们编写了一个 EasyThread 类 继承了 Thread 类，重写了 run 方法。

特别的是 EasyThread 可以直接调用 Thread 的构造函数。在方法1下，Thread 提供2种构造函数:

* Thread(), 创建一个线程对象
* Thread(String name), 创建一个指定名称的线程对象

线程的任务非常简单, 输出数字0-9。

值得一提的是, thread.getName()  方法返回当前线程的名称。

```java
public  class EasyThread extends Thread{
    public EasyThread(String name){
        super(name);
    }

    public EasyThread(){
    }

    //线程的启动需要重写 run 方法
    @Override
    public void run(){
        for (int i = 0; i < 10; i++) {
            System.out.println(this.getName()+"线程正在执行"+"第"+i+"次for循环");
        }
    }
}
```

我们编写了一个测试类 EasyThreadDemo。这里面我们实现了两个线程 mt1 和 mt2 。线程的启动需要调用线程对象的 start()方法。两个线程任务相同。

```java
public class EasyThreadDemo {
    public static void main(String[] args) {
        EasyThread mt1=new EasyThread("mt1");
        mt1.start();//启动线程, star()方法去启动run()方法

        EasyThread mt2=new EasyThread("mt2");
        mt2.start();

    }
}
```

运行结果：

```
mt1线程正在执行第0次for循环
mt2线程正在执行第0次for循环
mt2线程正在执行第1次for循环
mt2线程正在执行第2次for循环
mt2线程正在执行第3次for循环
mt2线程正在执行第4次for循环
mt2线程正在执行第5次for循环
mt2线程正在执行第6次for循环
mt2线程正在执行第7次for循环
mt2线程正在执行第8次for循环
mt2线程正在执行第9次for循环
mt1线程正在执行第1次for循环
mt1线程正在执行第2次for循环
mt1线程正在执行第3次for循环
mt1线程正在执行第4次for循环
mt1线程正在执行第5次for循环
mt1线程正在执行第6次for循环
mt1线程正在执行第7次for循环
mt1线程正在执行第8次for循环
mt1线程正在执行第9次for循环

```

可以看出多线程的执行顺序和我们在 main 函数里面所写的顺序不同。main 函数里面明明是先启动了 mt1 线程，但是执行的时候却是 mt2 线程 先执行。

而事实上，**线程的实行顺序是随机的，或者说是由操作系统动态决定的！**

上图中的执行顺序也是不确定，可能每一次运行的执行顺序都不同

## 方法2实现多**线程**:

我们编写了一个 RunnableThread 类, 实现了 Runnable 接口， 重写了run 方法。

然后将 实现了 Runnable 接口 的对象传给 Thread 类，构建一个线程对象。在此种方法下，Thread 也提供2种构造函数:&#x20;

* Thread(Runnable target), 创建一个线程对象
* Thread(Runnable target, String name), 创建一个指定名称的线程对象

线程的任务非常简单, 也是输出数字0-9。

值得一提的, Thread.currentThread().getName() 也能获取当前线程的名城

```java
public class RunnableThread implements  Runnable{

    @Override
    public void run() {
        for (int i=0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+"正在运行"+"第"+i+"次for循环.");
        }

    }
}
```

我们编写了一个测试类，实例化了一个实现Runnable 接口的对象, 将这个对象传给  Thread, 构建了两个线程。

```java
public class RunnableThreadDemo {
    public static void main(String[] args) {
        //创建 实现 Runnable 接口的对象
        RunnableThread rt= new RunnableThread();

        //创建线程,传入实现Runnable接口的对象
        Thread t1=new Thread(rt,"runnable thread 1");

        //启动线程
        t1.start();

        //将同一个 实现 Runnable 接口的对象 传给多个线程
        //相当于多线程共同处理 实现 Runnable 接口的对象 内的数据
        Thread t2=new Thread(rt,"runnable thread 2");
        t2.start();

    }

}
```

运行结果：

```
runnable thread 1正在运行第0次for循环.
runnable thread 2正在运行第0次for循环.
runnable thread 1正在运行第1次for循环.
runnable thread 2正在运行第1次for循环.
runnable thread 2正在运行第2次for循环.
runnable thread 1正在运行第2次for循环.
runnable thread 2正在运行第3次for循环.
runnable thread 1正在运行第3次for循环.
runnable thread 2正在运行第4次for循环.
runnable thread 1正在运行第4次for循环.
runnable thread 2正在运行第5次for循环.
runnable thread 1正在运行第5次for循环.
runnable thread 2正在运行第6次for循环.
runnable thread 2正在运行第7次for循环.
runnable thread 2正在运行第8次for循环.
runnable thread 2正在运行第9次for循环.
runnable thread 1正在运行第6次for循环.
runnable thread 1正在运行第7次for循环.
runnable thread 1正在运行第8次for循环.
runnable thread 1正在运行第9次for循环.
```

这个例子进一步看出, 线程的执行顺序是随机的, 是交替执行的。具体来说，**线程的执行顺序是由操作系统动态决定的。**
