1. Java 中多线程的实现
主要有三种方案:
- 继承 Thread 类,并重写 run() 方法
- 实现 Runnable 接口,并重写 run() 方法
- 实现 Callable 接口,并重写 call() 方法
其中前两种比较常见。
1.1 Thread 类
继承 Thread 类,并重写 run() 方法。
Thread 类底层也是实现了 Runnable 接口,并重写了 run() 方法。
调用 start() 方法后,JVM为创建一个新的线程,并将该线程设置为可运行态 Runnable,但并没有直接运行。
- 当线程第一次得到时间片时,run()方法得以运行。
public class Demo {
    public static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("MyThread");
        }
    }
    public static void main(String[] args) {
        Thread myThread = new MyThread();
        myThread.start();
    }
}start() 方法不可被多次调用,否则会抛出异常。
1.1.1 Thread 类常用方法
- Thread.currentThread():静态方法,返回对当前正在执行线程对象的引用
- start(): 开始线程,把新线程设置为就绪态。
- run(): 线程获得时间片时,自动被异步调用,真正开始执行该线程。- 该方法实现自 Runnable接口。
 
- 该方法实现自 
- yield():让出当前的 CPU 时间片,并重新变成就绪状态,重新竞争 CPU。- 让出后,可能当前 CPU 使用权还会被该线程获取到。
 
- Thread.sleep(): 静态方法,让当前线程睡眠一段时间。
- join(): 让当前线程等待另一个线程执行完毕后再继续执行。- 底层是使用的 Object类的wait()方法
 
- 底层是使用的 
yield() 和 sleep() 的异同
- 都能暂停当前线程,yield() 依赖于 CPU 时间片划分,sleep() 可以指定具体休眠时间
- 二者若持有锁,则在暂停线程时都不会释放锁
- yield() 不能被中断,sleep() 可以被中断
1.2 Runnable 接口
Runnable 接口是一个函数式接口,支持函数式编程。
@FunctionalInterface
public interface Runnable {
    public abstract void run();
}通过 Runnable 接口来创建并启动线程,有两种方式:
- 通过 普通类 的方式或 函数式编程匿名类 的方式来创建 Runnable接口的实现类,并实现run()方法。
- 传入 Runnable的实现类,实例化Thread类对象。
- 调用 start()方法来启动该线程。
public class Demo {
    public static class MyThread implements Runnable {
        @Override
        public void run() {
            System.out.println("MyThread");
        }
    }
    public static void main(String[] args) {
        // 通过 Thread 类来创建新线程
        new Thread(new MyThread()).start();
        // Java 8 函数式编程,创建匿名类
        new Thread(() -> {
            System.out.println("Java 8 匿名内部类");
        }).start();
    }
}1.3 联系与区别
继承 Thread 类或者实现 Runnable 接口,最终都是通过创建 Thread 对象来控制线程的创建。
推荐使用 Runnable 的方式来实现多线程。
 
                        
                        