多线程的生命周期以及多线程的使用场景

Posted 四猿外

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程的生命周期以及多线程的使用场景相关的知识,希望对你有一定的参考价值。

多线程

Java 中的多线程就是利用多个线程共同完成一个大任务的运行过程,使用多线程可以最大程度的利用CPU。

使用多线程的使用线程而不是进程来做任务处理,是因为线程比进程更加轻量,线程是一个轻量级的进程,是程序执行的最小单元,并且线程和线程之间是共享主内存的,而进程不是。

线程生命周期

在这里插入图片描述

正如上图所示,线程生命周期一共有六种状态。我们现在依次对这些状态进行介绍。

  1. New:当我们构造出一个线程实例的时候, 这个线程就拥有了 New 状态。这个状态是线程的第一个状态。此时,线程并没有准备运行。
  2. Runnable:当调用了线程类的 start() 方法, 那么这个线程就会从 New 状态转换到 Runnable 状态。这就意味着这个线程要准备运行了。但是,如果线程真的要运行起来,就需要线程调度器来调度执行这个线程。但是线程调度器可能忙于在执行其他的线程,从而不能及时去调度执行这个线程。线程调度器是基于 FIFO 策略去从线程池中挑出一个线程来执行的。
  3. Blocked:线程可能会因为不同的情况自动的转为 Blocked 状态。比如,等候 I/O 操作,等候网络连接等等。除此之外,任意的优先级比当前正在运行的线程高的线程都可能会使得正在运行的线程转为 Blocked 状态。
  4. Waiting:在同步块中调用被同步对象的 wait 方法,当前线程就会进入 Waiting 状态。如果在另一个线程中的同一个对象被同步的同步块中调用 notify()/notifyAll(),就可能使得在 Waiting 的线程转入 Runnable 状态。
  5. Timed_Waiting:同 Waiting 状态,只是会有个时间限制,当超时了,线程会自动进入 Runnable 状态。
  6. Terminated:线程在线程的 run() 方法执行完毕后或者异常退出run()方法后,就会进入 Terminated 状态。

为什么要使用多线程

大白话讲就是通过多线程同时做多件事情让 Java 应用程序跑的更快,使用线程来实行并行和并发。如今的 CPU 都是多核并且频率很高,如果单独一个线程,并没有充分利用多核 CPU 的优势。

重要的优势

  • 可以更好地利用 CPU
  • 可以更好地提升和响应性相关的用户体验
  • 可以减少响应时间
  • 可以同时服务多个客户端

创建线程有两种方式

  1. 通过继承Thread类创建线程

这个继承类会重写 Thread 类的 run() 方法。一个线程的真正运行是从 run() 方法内部开始的,通过 start() 方法会去调用这个线程的 run() 方法。

public class MultithreadDemo extends Thread {
    @Override
    public void run() {
        try {
            System.out.println("线程 " + Thread.currentThread().getName() + " 现在正在运行");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            MultithreadDemo multithreadDemo = new MultithreadDemo();
            multithreadDemo.start();
        }
    }
}

  1. 通过实现Runnable接口创建线程

我们创建一个实现了 java.lang.Runnable 接口的新类,并实现其 run() 方法。然后我们会实例化一个 Thread 对象,并调用这个对象的 start() 方法。

public class MultithreadDemo implements Runnable {

    @Override
    public void run() {
        try {
            System.out.println("线程 " + Thread.currentThread().getName() + " 现在正在运行");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(new MultithreadDemo());
            thread.start();
        }
    }
}

两种创建方式对比

  • 如果一个类继承了 Thread 类,那么这个类就没办法继承别的任何类了。因为 Java 是单继承,不允许同时继承多个类。多继承只能采用接口的方式,一个类可以实现多个接口。所以,使用实现 Runnable 接口在实践中比继承 Thread 类更好一些。
  • 第一种创建方式,可以重写 yield()、interrupt() 等一些可能不太常用的方法。但是如果我们使用第二种方式去创建线程,则 yield() 等方法就无法重写了。

以上是关于多线程的生命周期以及多线程的使用场景的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程基础--线程生命周期与线程协作详解

Java多线程基础--线程生命周期与线程协作详解

iOS 多线程NSThread理解与场景示例

iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用

iOS多线程全套:线程生命周期,多线程的四种解决方案,线程安全问题,GCD的使用,NSOperation的使用(上)

Java多线程并发02——线程的生命周期与常用方法