多线程---线程的状态及常用方法

1. 线程的状态

        在Java程序中,一个线程对象通过调用start()方法启动线程,并且在线程获取CPU时,自动执行run()方法。run()方法执行完毕,代表线程的生命周期结束。

        在整个线程的生命周期中,线程的状态有以下六种:

New:新建状态,新创建的线程,此时尚未调用start()方法;

Runnable:运行状态,运行中的线程,已经调用了start()方法,线程正在或者即将调用run()方法;

Blocked:阻塞状态,运行中的程序在等待竞争锁时,被阻塞,暂不执行;

Waiting:等待状态,运行中的线程,因为join()等方法,进入等待;

Timed Waiting:计时等待状态,运行中的线程,因为执行sleep(等待时间)或join(等待时间)等方法,进入计时等待;

Terminated:终止状态,线程已经终止,因为run()方法执行完毕

 线程终止的原因有:
○线程正常终止:run()方法执行到return语句返回;
○线程意外终止:run()方法因为未捕获的异常导致线程终止;
○对某个线程的Thread实例调用stop()方法强制终止(不推荐使用);

2.线程的常用方法

2.1 线程的插队:join( )方法

作用:

        t.join()方法会使当前线程( 主线程 或者调用t.join()的线程 )进入等待池,并等待 线程t 执行完毕后才会被唤醒。此时,并不影响同一时刻处在运行状态的其他线程。

示例:
        myThread.join()被主线程调用,则主线程进入WAITING或者TIMED_WAITING(调用myThread.join(long millis))等待状态,主线程Main必须等子线程myThread执行完毕后才能继续执行。当子线程myThread执行完毕后,进入TERMINATED终止状态,会自动调用notifyAll()方法,唤醒主线程,主线程重新进入RUNNABLE运行状态,继续执行;

public class Test03_join {private static void printWithThread(String content) {System.out.println("[" + Thread.currentThread().getName() + "线程]" +content);}public static void main(String[] args) {printWithThread("开始执行main方法");Thread myThread = new Thread(new Runnable() {@Overridepublic void run() {printWithThread("我在自定义的线程的run方法里");printWithThread("我马上要休息1秒钟,并让出CPU给别的线程使用.");try {Thread.sleep(1000);printWithThread("已经休息了1秒,又重新获得了CPU");printWithThread("我休息好了,马上就退出了");}catch (InterruptedException e) {e.printStackTrace();}}});try {myThread.start();printWithThread("我在main方法里面,我要等下面这个线程执行完了才能继续往下执行.");myThread. join();printWithThread("我在main方法里面,马上就要退出了.");}catch (InterruptedException e) {e.printStackTrace();}}
}

//运行结果:

[main线程]开始执行main方法
[main线程]我在main方法里面,我要等下面这个线程执行完了才能继续往下执行.
[Thread-0线程]我在自定义的线程的run方法里
[Thread-0线程]我马上要休息1秒钟,并让出CPU给别的线程使用.
[Thread-0线程]已经休息了1秒,又重新获得了CPU
[Thread-0线程]我休息好了,马上就退出了
[main线程]我在main方法里面,马上就要退出了.

join( )方法的实现原理

○join()方法的底层是利用wait()方法实现;
○join()方法是一个synchronized同步方法,当主线程调用 线程t.join( )方法时,主线程先获得了 线程t对象 的锁,随后进入join()方法,调用 线程t对象 的wait()方法,使主线程进入了 线程t对象 的等待池;
○等到 线程t 执行完毕之后,线程在TERMINATED终止状态的时候会自动调用自身的notifyAll()方法,来唤醒所有处于等待状态的线程:这个机制在隐藏在native本地方法中,由一个C++实现的方法ensure_join()函数实现。在该函数的尾部,执行了lock.notify_all(thread);,相当于调用了notifyAll()方法。

        综上所述:join()方法实际上是通过调用wait()方法, 来实现同步的效果的。
        例如:A线程中调用了B线程的join()方法,则相当于A线程调用了B线程的wait()方法,在调用了B线程的wait()方法后,A线程就会进入WAITING或者TIMED_WAITING等待状态,因为它相当于放弃了CPU的使用权。
        注意:join(0)的意思不是A线程等待B线程0秒,而是A线程等待B线程无限时间,直到B线程执行完毕:即join(0)=join();

        join()方法的源代码:

join( )方法和wait( )方法的区别

①定义的类不同

○sleep()方法是Thread类的静态方法

○wait()方法是Object类的方法

②锁的释放不同

sleep()方法不会释放任何锁,如果一个线程正在执行同步代码块或方法并且调用sleep()方法,它将继续持有该对象的锁,直到睡眠时间结束

wait()方法会释放当前线程持有的锁,允许其他线程访问同步代码块或方法。当线程被唤醒并重新竞争到锁后才能继续执行。

③调用位置不同

sleep()方法可以在任何地方调用,不需要在同步块或方法内;

wait()方法必须在同步块或方法中调用,因为它是 Object类的方法,通常在持有对象锁的情况下调用;

④唤醒机制不同

sleep()方法在指定的时间过后会自动恢复线程的执行;

wait() 方法需要被其他线程调用 notify()或 notifyA11()方法来唤醒,除非使用 wait(long timeout) 指定

超时时间,否则线程会一直等待直到被显式唤醒;

⑤异常抛出不同

sleep() 方法可能会抛出 InterruptedException(如果线程在睡眠期间被中断);

wait() 方法除了会抛出InterruptedException 以外,如果没有在同步代码块中调用,还会抛出 IllegalMonitorStateException

⑥作用目的

sleep()主要用于暂停线程的执行,可以用于定时任务、延迟执行等情况;

wait()主要用于线程间的通信和同步,如生产者消费者模型中等待资源可用或通知其他线程;

⑦sleep()和 wait()的主要区别在于锁的处理、调用环境和唤醒机制。用于线程之间的同步和通信。

sleep() 是一个简单的延时机制,而 wait()则

join( )方法和sleep( )方法的区别

两个方法都可以实现类似"线程等待"的效果,但是仍然有区别;
○join()是通过在内部使用synchronized + wait()方法来实现的,所以join()方法调用结束后,会释放锁
sleep()休眠没有结束前,不会释放锁

2.2 线程的中断:interrupt( )方法

        如果线程需要执行一个长时间任务,就可能需要能中断线程。中断线程就是其他线程给该线程发一个信号,该线程收到信号后结束执行run()方法,使得自身线程能立刻结束运行。
例如:假设从网络下载一个100M的文件,如果网速很慢,用户等得不耐烦,就可能在下载过程中点“取消”,这时,程序就需要中断下载线程的执行。
中断一个线程非常简单,只需要在其他线程中对目标线程调用interrupt()方法,目标线程需要反复检测自身状态是否是interrupted状态,如果是,就立刻结束运行。

interrupt( )方法的作用

        interrupt()方法的作用是设置该线程的中断状态为true,线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于中断状态。线程会不时地检测这个中断状态值,以判断线程是否应该被中断(中断状态值是否为true)。

interrupt( )方法的原理

        interrupt()方法只是改变中断状态,不会像stop()中断一个正在运行的线程。支持线程中断的方法(Thread.sleep() 、join()、wait()等方法)就是在监视线程的中断状态,一旦发现线程的中断状态值被置为“true”,就会抛出线程中断的异常InterruptedException,给WAITING或者TIMED_WAITING等待状态的线程发出一个中断信号,线程检查中断标识,就会以退出WAITING或者TIMED_WAITING等待状态。

注意事项:

●线程被Object.wait(), Thread.join()和Thread.sleep()三种方法阻塞或等待,此时调用该线程的interrupt()方法,那么该线程将抛出一个 InterruptedException中断异常,从而提前终结被阻塞状态。
如果线程没有被阻塞或等待,调用 interrupt()将不起作用,直到执行到wait(),sleep(),join()等方法进入阻塞或等待时,才会抛出 InterruptedException异常

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/144013.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

前海桂湾的海边免费停车场

​前海很多打工人晚上加班前海边散步的地方。相信很多前海打工人都曾经路过这个免费的停车场。坐标出于滨海大道的断头路区域。 看卫星地图可以发现,是个断头路,但是面积还是很大,停个几十辆车没问题。我就停过一次,周末带娃来这里…

ESP8266+使用串口1打印LOG+释放串口0

Menuconfig配置 具体的位置位于Component config > Common ESP-related 配置后,串口0上电还是会打印一些信息,除此之外就不打印了。 ets Jan 8 2013,rst cause:2, boot mode:(3,6)load 0x40100000, len 7792, room 16 tail 0 chksum 0x44 load 0…

Lab2 【哈工大_操作系统】操作系统的引导

本节将更新哈工大《操作系统》课程第二个 Lab 实验 操作系统的引导。按照实验书要求,介绍了非常详细的实验操作流程,并提供了超级无敌详细的代码注释。文末附完整 bootsect.s 和 setup.s 标准答案代码以及超详细注释。 实验目的: 熟悉 hit-o…

C语言中的assert断言

Assert断言 断言是程序中处理异常的一种高级形式。可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言,而在部署时禁用断言。同样,程序投入运行后,最终用户在遇到问题时可以重新启用断言。 用法: #…

AD域控服务器

1.AD域控服务器安装 2.客户端Windows10加入域环境 3.组织单位OU和域用户创建 目的是分部门管理用户和使用域用户登录客户端 4.域用户安全策略 5.当客户端密码锁住了,管理员解锁账户。 6.只允许域用户使用自己的电脑 7.域策略 7.1统一客户端桌面壁纸 7.2重定向用户配置文件路径…

软件设计画图,流程图、甘特图、时间轴图、系统架构图、网络拓扑图、E-R图、思维导图

目录 一、流程图 二、甘特图 三、时间轴图 四、系统架构图 五、网络拓扑图 六、E-R图 七、思维导图 一、流程图 是一种用符号表示算法、工作流或流程的图形。用不同的图形表示不同含义,如椭圆表示开始和结束、菱形表示判断等。 画图工具WPS office 应用市场…

如何使用ssm实现基于vue.js的购物商场的设计与实现+vue

TOC ssm616基于vue.js的购物商场的设计与实现vue 第1章 绪论 1.1选题动因 当前的网络技术,软件技术等都具备成熟的理论基础,市场上也出现各种技术开发的软件,这些软件都被用于各个领域,包括生活和工作的领域。随着电脑和笔记本…

如何使用ssm实现基于ssm框架的车辆出租管理系统+vue

TOC ssm643基于ssm框架的车辆出租管理系统vue 第1章 绪论 1.1 课题背景 二十一世纪互联网的出现,改变了几千年以来人们的生活,不仅仅是生活物资的丰富,还有精神层次的丰富。在互联网诞生之前,地域位置往往是人们思想上不可跨域…

LeetCode_sql_day28(1767.寻找没有被执行的任务对)

描述:1767.寻找没有被执行的任务对 表:Tasks ------------------------- | Column Name | Type | ------------------------- | task_id | int | | subtasks_count | int | ------------------------- task_id 具有唯一值的列。 ta…

7iDU AMP田岛绣花机驱动器维修0J2100400022

7iDU AMP神州田岛绣花机驱动器维修0J2101300000绣花机控制器等全系列型号均可处理。 田岛7iDU AMP是田岛绣花机中使用很广的一种5相驱动器,在田岛平绣车TMEF-H,TMFD中应用,在链条车TMCE112S,和盘带车TMLG中大量使用。其采用的东芝…

面试或工作中的经典问题共享

前言:大家可以把面试或工作中遇到了经典问题共享一下,我们共同学习成长,金九银十,祝各位都能步步高升! 文档大家可以往下追加,请勿删除他人编写的内容哦。我会把问题的相关资料进行补充,以便各…

HTB-Blue(永恒之蓝漏洞复现)

前言 各位师傅大家好,我是qmx_07,今天给大家讲解Blue靶机 渗透过程 信息搜集 服务器开放了smb服务,漏洞探测显示 具有ms17_010(永恒之蓝漏洞) 利用永恒之蓝 搜索永恒之蓝漏洞 use使用永恒之蓝漏洞 rhost //对方主机 lhost //回连主机 …

[学习笔记]树链剖分(简易版) 及其LCA

树链剖分 先讲解一下一些基础定义(都是在树上) 重儿子: 一个节点中所有儿子中子树大小最大的一个儿子(每个节点最多有一个重儿子)轻儿子: 一个节点除重儿子外所有的节点重链: 若干个重儿子组成的链链顶: 一条链中深度最小的节点 以下图为例子 (红色连续线段为重链) 对于节点…

【LabVIEW】事件结构的用法

本篇文章记录我学习LabVIEW的事件结构用法,希望我的分享对你有所帮助! 目录 一、案例说明 1、 LabVIEW实现“YAXBXC的计算” 2、添加事件结构 一、案例说明 在LabVIEW实现“YAXBXC的计算”的基础上,加上事件结构,实现单击一次按…

分布式锁总结2 - redis实现分布式锁并解决常见问题

目录 1. redis分布式锁 1.1基本原理图示如下 1.2 Redis通过一个lock变量实现一个最简单的分布式锁实现代码: 2 升级简单分布式锁(实现原子加锁与安全删锁) 2.1 但1中的简单分布式锁存在几个问题: 2.1.1 问题1. 如果加完锁执…

Vue.js魔法书:前端开发者的终极指南----指令篇续篇

​个人名片: 😊作者简介:一个为了让更多人看见许舒雅的宝贝的小白先生 🤡个人主页:🔗 许舒雅的宝贝 🐼座右铭:深夜两点半的夜灯依旧闪烁,凌晨四点的闹钟不止你一个。 &am…

计算机网络32——Linux-文件io-2文件系统

1、阻塞和非阻塞 想要将文件以非阻塞方式打开,有两种方式 (1)需要将文件关闭,再用非阻塞方式打开 (2)fctnl函数,先获取旧属性,再添加一个新属性 阻塞函数 阻塞函数一直在等待输入…

MATLAB系列09:图形句柄

MATLAB系列09:图形句柄 9. 图形句柄9.1 MATLAB图形系统9.2 对象句柄9.3 对象属性的检测和更改9.3.1 在创建对象时改变对象的属性9.3.2 对象创建后改变对象的属性 9.4 用 set 函数列出可能属性值9.5 自定义数据9.6 对象查找9.7 用鼠标选择对象9.8 位置和单位9.8.1 图…

使用微信小程序唤起导航的常用方式

1.微信内置地图 可以使用小程序的wx.openLocation方法,该方法可以打开微信内置地图,并显示指定的位置坐标。如果用户手机上安装了其他地图应用,可能会出现选择使用哪个地图应用进行导航的提示。 wx.openLocation({latitude: 目标地点纬度,lo…

滑动窗口(7)_串联所有单词的字串

目录 1. 题目链接: 2. 题目描述 : 3. 解法 : 题目解析: 算法思路 : 图解流程: 代码展示 : 结果分析 : 1. 题目链接: OJ链接:串联所有单词的字串 2. 题目描述 : 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 w…