Java 多线程学习(一):线程

2021年11月24日 阅读数:4
这篇文章主要向大家介绍Java 多线程学习(一):线程,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

(编写时间:2017-11-27 15:22:16)html

线程,做为CPU调度的最基本单位以及任务的执行者,其存在的数量决定了程序的执行吞吐量。java

做为虚拟机,JVM也对物理计算机的多线程技术进行了实现,即在一个JVM虚拟机内能够执行多个Java线程。而对于物理机而言,绝大多数操做系统针对JVM是把内核线程(kernel thread)与 JVM线程进行一一对应的。git

上面这些理解起来可能会比较绕,简单来讲: 物理计算机中一个JVM进程拥有多个内核线程(kernel thread),一个内核线程对应JVM中的Java线程(java.lang.Thread)。github

以下图:
编程

因此,对于JVM而言其部署的服务器的可开启的最大线程数既是JVM可开启的最大线程数。安全

线程的建立与运行

使用Thread类建立多线程应用有两种方式:服务器

1. 继承`java.lang.Thread`基础线程对象,并覆写其中的 `run()` 方法。  
2. 实现`java.lang.Runnable`接口的`run()`方法,并new Thread对象传入Runnable接口实现对象。  

相对于继承Thread类而实现多线程的方式,我的更推荐使用实现Runnable接口的方式实现多线程,主要的优点有:多线程

1. 避免java单继承特性带来的局限性
2. 加强程序的健壮性,代码可以被多个线程共享,代码与数据是独立的
3. 适合多个相同程序代码的线程区处理同一资源的状况  

最后,完成线程对象的建立事后,使用 start() 方法启动线程。并发

对于Thread类来讲,使用start()方法并非当即执行多线程代码,而是将该线程变成可运行态(Runnable),实际运行时间是由操做系统决定的。jvm

线程状态

在线程建立成功到结束任务的过程当中线程都会拥有一个状态。这个状态在Thread的内部枚举类State中定义了:

public enum State {
	/**
     * 还没有开始状态
     * 
     * 新建且未执行start()方法的线程的状态
     */
    NEW,

    /**
     * 等待执行状态
     * 
     * 已执行start()方法正在等待CPU执行的线程状态
     */
    RUNNABLE,

	/**
     * 阻塞状态
     * 
     * 该线程所需的资源被其余线程占用(blocked),线程进入等待资源释放的状态
     */
    BLOCKED,

	/**
     * 无限等待状态
     * 
     * 等待其他线程调用该线程的notify()或notifyAll()方法才能解除这个状态
     */
    WAITING,

	/**
     * 有时间限制的等待状态
     * 
     * 等待时间限制结束解除等待状态,
     * 或调用该线程的notify()或notifyAll()方法亦能解除该状态
     */
    TIMED_WAITING,

	/**
     * 线程停止的状态,这个线程已经完整地执行了它的任务
     */
    TERMINATED;
}

上面的代码注释中已经简单对每个状态进行了简单的说明,其中阻塞状态和两种等待状态我将在下一篇博文中对同步与线程锁进行详细的介绍。

线程的中止

自动中止

正常状况下,线程任务完成事后就会自动结束生命周期,并设置状态为TERMINATED

public static void main(String[] args) throws ExecutionException, InterruptedException {
    Thread threadA = new Thread();
    threadA.start();
    Thread.sleep(1000);
    System.out.println(threadA.getState().name());	//结果为:TERMINATED
}

当线程出现错误的时候,会当即结束生命周期,并设置状态为TERMINATED

public class ThrowExceptionRunnable implements Runnable {
    @Override
    public void run() {
        try {
            throw new Exception("123");
        } catch (Exception e) {
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new ThrowExceptionRunnable());
        thread.start();
        Thread.sleep(1000);
        System.out.println(thread.getState().name());	//结果为:TERMINATED
    }
}

手动中止

手动中止线程的方法有以下四种:

1. 异常中止:利用线程错误自动中止的机制,抛出异常使线程中止。
2. 暴力中止:调用线程的`stop()`方法,可是这个方法已经设置为过期。由于会致使某些收尾程序未完成,对象"解锁",致使数据不一样步。
3. 使用return中止线程:当方法执行的代码遇到了return时,这个方法就会结束。若是在`run()`方法中使用return也就表明了线程的执行结束。
4. 使用`interrupt()`方法使中断状态的线程结束运行

因为篇幅缘由,最后的一个中止线程的方法就没法详细分析了,你们能够参考如下两篇文章:

结束

本文部分文原本源于互联网

感谢如下文章提供的灵感和帮助