Java Core 「1」JUC-线程基础

235 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情

01-线程状态

  • NEW

    // 线程创建后,线程的状态为 NEW
    Thread t = new Thread(new Runnable() {...});
    
  • RUNNABLE

    // 调用线程的 start 方法后,线程状态变为 RUNNABLE
    t.start();
    

    注:此时线程正在被 JVM 执行,但是并不见得真的在 CPU 上执行,有可能在等待 CPU 的时间片

  • BLOCKED

    线程等待 monitor 锁时,会进入到阻塞状态。

  • WAITING / TIMED_WAITING

    • Object.wait() / Thread.join() / LockSupport.park() 导致线程进入 WAITING 状态,即等待其他的线程调用 Object.notify() / Object.notifyAll() / 线程执行完毕 / LockSupport.unpark()
    • 带超时版本的上述方法会使线程进入 TIMED_WAITING 状态
    • 此外,Thread.sleep() 也会使线程进入到 TIMED_WAITING 状态
  • TERMINATED

    线程执行完毕后(正常或异常退出),该线程进入到 TERMINATED 状态

Life_cycle_of_a_Thread_in_Java.jpg

02-创建线程的方式

  1. 继承 Thread 类

    class MyThreadA extends Thread {
    	@Override
    	public void run() {
    		// ....
    	}
    }
    
  2. 实现 Runnable 接口

    class MyThreadB implements Runnable {
    	@Override
    	public void run() {
    		// ...
    	}
    }
    
  3. 实现 Callable 接口

    class MyThreadC implements Callable {
    	@Override
        public Object call() throws Exception {
            return null;
        }
    }
    

注:实现 Runnable 与 继承 Thread 类的区别是,前者更灵活、方便;Runnable 与 Callable 的区别是,前者的 run 方法无法返回值,而后者的 call 方法可以设定返回值。

03-线程的启动方式

  1. Thread.start() 方法(结合 02 中线程创建方式)

    // 继承 Thread 或实现 Runnable 接口
    Thread ta = new MyThreadA(); ta.start();
    Thread tb = new Thread(new MyThreadB()); tb.start();
    
    // 实现 Callable 接口
    FutureTask<Object> ft = new FutureTask<>(new MyThreadC());
    Thread tc = new Thread(ft, "name"); tc.start();
    
  2. ExecutorService 框架

    • 可通过工具类 Executors 快捷地创建不同类型的线程池(阿里开发手册并不推荐这么做,原因是容易忽略线程池的内部逻辑,从而造成性能问题,推荐使用 ThreadPoolExecutor 方式)
      • cached thread pool
      • fixed thread pool
      • single thread pool
      • scheduled thread pool
      • work stealing pool
    • 提交任务到线程池(Runnable 或 Callable 对象)
      • execute,无返回值
      • submit,有返回值,Future (更多信息参考[1])
  3. CompletableFuture,更多信息参考[2]

    CompletableFuture.supplyAsync(() -> "Hello");