Java这些多线程基础知识你会吗?

作者 : 开心源码 本文共2402个字,预计阅读时间需要7分钟 发布时间: 2022-05-12 共176人阅读

0、并发和并行、进程核线程、多进程和多线程的区别:

(这里的时间和时刻上的概念同物理上的一样)

并发:在一段时间内多个任务同时执行,或者者说是在一段很短的时间内可以执行多条程序指令,微观上看起来如同是可以同时运行多个进程,单核解决器即可以做到。

并行:在同一时刻多个任务同时执行,或者者说是在同一时刻可以执行多条程序指令,多核解决器才可以做到。

进程:进程是程序的一次执行过程,是系统运行程序的基本单位,打开 Windows 的任务管理器即可以看到很多进程。

线程:线程与进程类似,但线程是一个比进程更小的执行单位,一个进程在其执行的过程中可能产生多个线程。

多进程:每个进程都拥有自己独立的资源,多个进程可在单核解决器上并发执行,在多核解决器上并行执行。

多线程:一个进程可由多个线程组成,多个线程共享进程内资源,多个线程可在单核解决器上并发执行,在多核解决器并行执行。

在多核解决器上,并发和并行同时存在,解决器上的每个核同一时刻同时执行多个任务,每个核在很短的时间段内又同时执行多个任务,对多任务粗略划分是多个进程,对进程划分可能又是多个线程。同一时刻,解决器的每个核只能运行一个进程中的一个线程中的一条指令(Intel 的超线程技术,如双核四线程,四核八线程,解决器的线程(硬件上)和进程中的线程(软件上)不是一个概念,这个所谓的超线程技术也并不能达到真正的多核,只是尽可能的提高解决器的吞吐量核利用率)。

线程比进程更加的轻量级,进程和线程都是提高程序并发性和系统性能的手段,但并不是说进程越多或者线程越多,性能越高,还要结合硬件设施和操作系统来看。

1、创立线程的三种方式:

  • 继承 Thread 类,覆写父类中的 run() 方法,新线程类创立线程

  • 实现 Runnable 接口,实现接口中的 run() 方法,Thread 类创立线程

  • 实现 Callable 接口,FutureTask 类构造创立方法体,Thread 类创立线程

image

(扫一扫就可查看测试代码)

2、三种方式的优劣:

image

3、线程的六种状态:

Thread.State 枚举类中的定义

  • NEW:还没开始运行的线程处于这种状态

  • RUNNABLE:在 Java 虚拟机中可运行的线程(正在运行也可能没在运行)处于这种状态

  • BLOCKED:被阻塞而等待监视锁的线程处于这种状态

  • WAITING:无限期的等待另一个线程执行特定方法的线程处于这种状态

  • TIMED_WAITING:在指定等待时间内等待另一个线程执行特定的方法的线程处于这种状态

  • TERMINATED:已经退出(运行结束)的线程处于这种状态

image

4、线程的生命周期:

image

5、线程的分类:

1、普通线程:前端线程

2、守护线程

后端线程,运行在后端为其余线程提供服务,假如所有的前端线程都死亡,后端线程也自动死亡。当整个虚拟机中只剩下后端线程,虚拟机也没有继续运行的必要了,虚拟机也就退出了。

应用:JVM 虚拟机启动后的后端检测线程,数据库连接池中的检测线程。

最常见的守护线程:虚拟机中的垃圾回收线程,可以通过 jconsole,jvisualvm 等工具查看。

6、线程中的常用方法说明:

  • start()

    在使用 new 关键字创立一个线程后(New 状态),并不体现出任何的线程活动状态(非 New、Terminated 状态,可以使用 isAlive 方法检测线程的活动状态),CPU 也不会执行线程中的代码。

    只有在 start() 方法执行后,才表示这个线程可运行了(Runnable 状态),至于何时真正运行还要看线程调度器的调度。

    在线程死亡后,不要再次调用 start() 方法。只能对新建状态的线程调用且只能调用一次 start() 方法,否则将抛出 IllegalThreadStateException 异常。

  • run()

    启动线程是 start() 方法,而不是 run() 方法。

    假如直接调用 run() 方法,这个线程中的代码会被立即执行,多个线程就无法并发执行了。

  • join()

    等待该线程完成的方法,其余线程将进入等待状态(Waiting 状态),通常由使用线程的程序(线程)调用,如将一个大问题分割为许多小问题,要等待所有的小问题解决后,再进行下一步操作。

  • sleep()

    主动放弃占用的解决器资源,该线程进入阻塞状态(Blocked 状态),指定的睡眠时间超时后,线程进入就绪状态(Runnable),等待线程调度器的调用。

  • yield()

    主动放弃占用的解决器资源,线程直接进入就绪状态(Runnable),等待线程调度器的调用。

    可能的情况是当线程使用 yield 方法放弃执行后,线程调度器又将该线程调度执行。

  • interrupt():

    没有任何强制线程终止的方法,这个方法只是请求线程终止,而实际上线程并不肯定会终止,在调用 sleep() 方法时可能会出现 InterruptedException 异常,你可能会想在异常捕获后(try-catch语句中的catch)请求线程终止,而更好的选择是不解决这个异常,抛给调用者解决,所以这个方法并没有实际的用途,还有 isInterrupted() 方法检查线程能否被中断。

  • setDaemon()

    设置守护进程,该方法必需在 start() 方法之前调用,判断一个线程是不是守护线程,可以使用 isDaemon() 方法判断。

  • setPriority()

    设置线程的优先级,理论上来说,线程优先级高的线程更容易被执行,但也要结合具体的系统。

    每个线程默认的优先级和父线程(如 main 线程、普通优先级)的优先级相同,线程优先级区间为 1~10,三个静态变量:MIN_PRIORITY = 1、NORM_PRIORITY = 5、MAX_PRIORITY = 10。

    使用 getPriority() 方法可以查看线程的优先级。

  • isAlive()

    检查线程能否处于活动状态,假如线程处于就绪、运行、阻塞状态,方法返回 true,假如线程处于新建和死亡状态,方法返回 false。

说明
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » Java这些多线程基础知识你会吗?

发表回复