多线程的学习路线如下:

三种创建线程的方式

  • 直接使用 Thread ```java // 自定义线程对象 class Thread1 extends Thread { @Override public void run() {
    1. // 线程需要执行的任务
    2. ......
    3. }
    }

// 创建线程对象 Thread1 t1 = new Thread1();


- Thread + Runnable
```java
class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程需要执行的任务
        ......
    }
}

// 创建任务类对象
MyRunnable runnable = new MyRunnable();
// 创建线程对象
Thread t2 = new Thread(runnable);
// 指定线程名字
// Thread t2 = new Thread(runnable, "t2");
  • Thread + Callable + FutureTask

虽然 Runnable 挺不错的,但是仍然有个缺点,那就是没办法获取任务的执行结果,因为它的 run 方法返回值是 void。这样,对于需要获取任务执行结果的线程来说,Callable 就成为了一个完美的选择。
截屏2022-02-15 上午11.38.00.png

class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        // 要执行的任务
        ......
        return 100;
    }
}
// 将 Callable 包装成 FutureTask,FutureTask也是一种Runnable
MyCallable callable = new MyCallable();
FutureTask<Integer> task = new FutureTask<>(callable);
// 创建线程对象
Thread t3 = new Thread(task);

callable 一般和FutureTask 在一起使用。 FutureTask 提供了异步且可中断的计算,实现了RunnableFuture 接口 (集成了Runnable 和 Future接口)。

经典面试题(为什么用start创建线程而不用 run)

调用run 方法并不会重开一个线程而是在主线程下运行普通的重写方法。
Thread 管理了线程的生命周期,所以一般创建一个Runnable 任务然后传递给Thread运行,

控制线程的方法

  • start / run
  • sleep / yield
  • join / join(long n)
  • interrupt
  • setDaemon 守护线程

    Java 内存模型

    和线程安全相关的三大性质

  1. 原子性:一个操作是不可中断的,要么全部执行成功要么全部失败。(也可以说是提供互斥访问,同一时刻只能有一个线程对数据进行操作)
  2. 可见行:当程序修改了共享变量后,其他线程能够立即得知这个修改。
  3. 有序性:编译器和处理器为了优化程序性能,会对指令序列进行重新排序。由于重排序的存在,可能导致多线程环境下程序运行结果出错的问题。 使用happens-before 来保证有序性。

    指令重排遵循的原则(数据依赖性和as-if-serial)

  • 编译器和处理器在重排序时,会遵守数据依赖性,它们不会改变存在数据依赖性关系的两个操作的执行顺序
  • as-if-serial 语义的意思是:不管怎么重排序,程序的执行结果不能被改变。编译器,runtime 和处理器都必须遵守 as-if-serial 语义

    如何保证原子性,可见性和有序性。

  1. 对于可见性,可以使用 volatile 关键字来保证,不仅如此,volatile 还能起到禁止指令重排的作用;另外, synchronized 和 final 这俩关键字也能保证可见性。
  2. 对于原子性,我们可以使用 和 java.util.concurrent.atomic 包中的原子类来保证。 原子类用CAS 来保证原子性。
  3. 有序性由happens-before 来保证。

    各种锁的概念

  • 悲观锁和乐观锁
  • 重量级锁和轻量级锁
  • 自旋锁
  • 偏向锁
  • 重入锁和不可重入锁
  • 公平锁和非公平锁
  • 共享锁和排他锁

    并发关键字

    synchronize, volatile, final。

    JUC 工具包

  • Lock 框架(locks 包)

  • 原子类(atomic 包)
  • 并发集合
  • 线程池
  • 工具类(countDownLatch, cyclicBarrier, semaphore, exchanger)

    重要考点

    ThreadLocal,线程隔离,必问高阶考点。