Skip to content

Java 多线程总结

Published: at 16:50:24

什么是进程

进程是程序运行资源分配的最小单位

进程是操作系统进行资源分配的最小单位,其中资源包括:CPU资源、内存空间、磁盘IO等。同一进程中的多条线程共享该进程的全部系统资源,而进程和进程之间是相互独立的。

进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。

进程可以分为用户进程和系统进程,凡是用于完成操作系统的各种功能的进程就是系统进程,它们就是处于运行状态下的操作系统本身;用户进程就是由用户启动的进程。

什么是线程

线程是CPU调度的最小单位,必须依赖于进程而存在

线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的、能独立运行的基本单位。它可以与同属一个进程的其他线程共享进程所拥有的全部资源。

线程是无处不在的,任何一个进程都必须要创建线程。

什么是并行运行

并行是指“并排行走”或“同时实行或实施”。 在操作系统中是指,一组程序按独立异步的速度执行,无论从微观还是宏观,程序都是一起执行的。

举个例子:高速公路有4条车道,同时最多可以有4辆车“并排通行”,这里就是并行;

什么是并发运行

在操作系统中,并发是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。

举个例子:高速公路有4条车道,同时最多可以有4辆车“并排通行”,这里是并行,当第5辆车开上高速路上时,有一个车道上至少有两辆车,他们就没办法“并排通行”,只能等前面的车走了,后面的车才能走;

Java 中的线程模型与调度

结论就是对于Sun JDK 来说,它的Windows版本和 Linux 版本都是使用的一对一线程模型来实现的,即一条线程就映射到一条轻量级进程中,因为 Windows 系统和 Linux 系统提供的线程模型都是一对一的。

JAVA 使用的是抢占式调度方式

具体的介绍分析可以看另一篇文章; Java 线程模型与线程调度

Java 线程多种实现方式

  1. 继承 Thread 类

    public class MyThread extends Thread {
        public void run() {
            // ...by: [https://jingling.im/](https://jingling.im/)
        }
    }
  2. 实现 Runnable 接口

    public class MyRunnable implements Runnable {
        public void run() {
            // ...by: [https://jingling.im/](https://jingling.im/)
        }
    }
  3. 实现 Callable 接口

    public class MyCallable implements Callable<Integer> {
        public Integer call() {
            return 123;// by: [https://jingling.im/](https://jingling.im/)
        }
    }
  4. 线程池 Executors

    Executors.newSingleThreadExecutor();
    Executors.newCachedThreadPool();
    Executors.newFixedThreadPool(1);
    ...by: [https://jingling.im/](https://jingling.im/)
  5. 线程池 ThreadPoolExecutor

    executorService = new ThreadPoolExecutor(MAX_WORKER_THREADS, MAX_WORKER_THREADS,
                                           10L, TimeUnit.MINUTES,
                                           new LinkedBlockingQueue<Runnable>(),
                                           threadFactory);

Java 线程状态

源码Thread.State 说明了一切,一共6个状态

public enum State {
    // 才开始new  还没有调用start()方法;by: [https://jingling.im/](https://jingling.im/)
    NEW,
    // 可运行状态, 正在运行或者等待操作系统资源
    RUNNABLE,
    // 阻塞状态,在等待一个监视器锁(也就是我们常说的synchronized)
    //或者在调用了Object.wait()方法且被notify()之后也会进入BLOCKED状态
    BLOCKED,
    //等待状态,在调用了以下方法后进入此状态
    // 1. Object.wait()无超时的方法后且未被notify()前,如果被notify()了会进入BLOCKED状态
    // 2. Thread.join()无超时的方法后
    // 3. LockSupport.park()无超时的方法后
    WAITING,
    //超时等待状态,在调用了以下方法后会进入超时等待状态
    //1. Thread.sleep()方法后【本文由公从号“彤哥读源码”原创】
    //2. Object.wait(timeout)方法后且未到超时时间前,如果达到超时了或被notify()了会进入BLOCKED状态
    //3. Thread.join(timeout)方法后
    //4. LockSupport.parkNanos(nanos)方法后
    //5. LockSupport.parkUntil(deadline)方法后
    TIMED_WAITING,
    // 终止状态, 线程已经执行完毕
    TERMINATED;
}

线程状态运行示意图:

精灵王-线程状态运行示意图

线程的常用属性和方法