Java多线程总结

多线程快速入门

一. 线程与进程区别:

1、线程:

每个正在系统上运行的程序都是一个进程,它是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。也可以把它理解为代码运行的上下文。所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务。通常由操作系统负责多个线程的调度和执行。

2、进程:

进程是所有线程的集合,每个进程包含一到多个线程。

总结:进程是所有线程的集合,每一个线程是进程中的一条执行路径。

二. 使用场景:

使用场景:

        在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,可以使用线程把占据时间长的程序中的任务放到后台去处理,释放一些珍贵的资源如内存占用等等。

注意:

        如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换,更多的线程需要更多的内存空间,线程的中止需要考虑其对程序运行的影响。通常块模型数据是在多个线程间共享的,需要防止线程死锁情况的发生。

三. 多线程创建方式:

1、继承Thread类,重写run方法

/** * 多线程创建  ——————  继承Thread类,实现run方法 */public class CreateThread {    public static void main(String[] args) {        System.out.println("多线程开始---");        //创建线程        mutilThread mutilThread = new mutilThread();        //开始线程        //run():只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。        //start():用来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法        System.out.println("多线程启动---");        mutilThread.start();        System.out.println("多线程结束---");    }    static class mutilThread extends Thread {        @Override        public void run() {            //run方法中为具体实现的代码            for (int i = 0; i < 10; i++) {                System.out.println("线程:" + i);            }        }    }}

运行结果:

springboot mybatis 多线程 mybatis多线程并发_阻塞状态

由此可见:调用start方法后,代码并没有从上往下执行,而是有一条新的执行分支。

2. 实现Runnable接口,重写run方法。

/*** 多线程创建  ——————  实现runnable接口,重写run方法 */public class CreateThread2 {    public static void main(String[] args) {        System.out.println("多线程开始---");        //创建线程        mutilThread mutilThread = new mutilThread();        //开始线程        //run():只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。        //start():用来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法        System.out.println("多线程启动---");        Thread thread = new Thread(mutilThread);        thread.start();        System.out.println("多线程结束---");    }    static class mutilThread implements Runnable {        @Override        public void run() {            for (int i = 0; i < 10; i++) {                System.out.println("线程:"+i);            }        }    }}

3. 使用匿名内部类方式创建

/** * 多线程创建  ——————  使用匿名内部类的方式创建 */public class CreateThread3 {    public static void main(String[] args) {        System.out.println("线程开始---");        Thread thread = new Thread(new Runnable() {            @Override            public void run() {                for (int i = 0; i < 10; i++) {                    System.out.println("线程" + i);                }            }        });        System.out.println("线程启动---");        thread.start();        System.out.println("线程结束---");    }}

四. 常用线程API及常用线程构造函数:

API

描述

start()

启动线程

currentThread()

获取当前线程对象

getID()

获取当前线程ID Thread-编号 该编号从0开始

getName()

获取当前线程名称

sleep(long mill)

休眠线程

stop()

停止线程

构造函数

描述

Thread()

分配一个新的 Thread 对象

Thread(String name)

分配一个新的 Thread对象,可指定线程名称。

Thread(Runable r)

分配一个新的 Thread 对象

Thread(Runable r, String name)

分配一个新的 Thread对象,可指定线程名称。

五. 线程运行状态:

springboot mybatis 多线程 mybatis多线程并发_System_02

      线程从创建到销毁最全可经历5种状态:新建状态 - 就绪状态 - 运行状态 - 阻塞状态 - 死亡状态。

1. 新建状态

    当new Thread()时,线程刚刚被创建,但未开始运行时,当前处于新建状态。

2. 就绪状态

    当调用线程的start()方法时,会创建线程运行的系统资源,并调度线程运行run()方法。当start()方法返回时,线程就处于就绪状态。处于就绪状态的线程不一定会立即运行run()方法,在此期间,线程还需同其他线程争夺CPU时间,只有获得CPU时间,才能运行线程。因此,在单线程CPU的计算机系统中,不同同时运行多线程,单个时刻,有且仅有一个线程处于运行状态。而其他线程则会处于就绪状态。而对于多个处于就绪状态的线程,则是有java运行时系统的线程调度程序(Thread scheduler)来统一调度分配的。

3. 运行状态

    当线程获取到CPU时,进入运行状态,执行run()方法。

4. 阻塞状态

阻塞状态产生的原因:

  1. 调用sleep()方法使线程进入睡眠状态;
  2. 线程调用一个在I/O上被阻塞的操作时,在未得到输入/输出返回结果前,线程一直处于阻塞状态;
  3. 线程试图获取锁的操作,当该锁被其他线程持有时,该线程会进入阻塞状态;
  4. 线程在等待某一出发条件时,会处于阻塞状态。

5. 死亡状态

死亡状态有两种:

  1. 通过run()方法执行完的正常死亡;
  2. 因为异常导致线程中途死亡。
    当需要判断线程是否处于死亡状态时,可调用alive()方法进行判断线程处于阻塞状态还是死亡状态。

六. 线程常见面试题:

1. 进程与线程的区别?

     程是所有线程的集合,每一个线程是进程中的一条执行路径,线程只是一条执行路径。

2. 为什么要用多线程?

     提高程序效率

3. 多线程创建方式?

    1、继承Thread类。

     2、实现Runnable接口。

     3、匿名内部类。

4. 继承Thread类好还是实现Runnable接口好?

    实现Runnable好,因为单继承多实现,实现了Runnable接口后可再继承其他,而继承了Thread类后无法继承其他。

5. 你在哪里用到了多线程?

    主要能体现到多线程提高程序效率。