线程2:线程的生命周期与控制

多线程的常用关键字及示例代码(synchronized、volatile) 1.synchronized synchornized可以修饰方法跟代码块,核心本质是锁对象,如果是static修饰的,也可以锁类变量 注意:理解Java对象在内存中的组成:对象头,实际数据,对齐填充,重点理解对象头中的 markword 线程拥有锁,锁的是对象,对象的头信息中,指向的指针是线程 偏向锁,自旋锁,轻量锁,重量锁 1.偏向锁:当程序没有竞争,取消同步操作,发生竞争时,升级为轻量锁 2.轻量锁:(对象的头信息markword中存放了锁的状态和线程持有的索)如果当前线程用cas将markword 阅读详情

1.线程的生命周期
线程是一个动态执行的过程,它也有一个从产生到死亡的过程。

(1)生命周期的五种状态

   新建(new Thread)
当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。
例如:Thread  t1=new Thread();

就绪(runnable)
线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();

运行(running)
线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。

死亡(dead)
当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。

自然终止:正常运行run()方法后终止

异常终止:调用stop()方法让一个线程终止运行

堵塞(blocked)
由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。

正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。

正在等待:调用wait()方法。(调用motify()方法回到就绪状态)


线程的优先级

  1.线程的优先级及设置

  线程的优先级是为了在多线程环境中便于系统对线程的调度,优先级高的线程将优先执行。

  一个线程的优先级设置遵从以下原则:

  线程创建时,子继承父的优先级。

  线程创建后,可通过调用setPriority()方法改变优先级。

  线程的优先级是1-10之间的正整数。

  1- MIN_PRIORITY

  10-MAX_PRIORITY

  5-NORM_PRIORITY

  如果什么都没有设置,默认值是5。

  但是不能依靠线程的优先级来决定线程的执行顺序。

 

  2.线程的调度策略

  线程调度器选择优先级最高的线程运行。但是,如果发生以下情况,就会终止线程的运行:

  线程体中调用了yield()方法,让出了对CPU的占用权。

  线程体中调用了sleep()方法,使线程进入睡眠状态。

  线程由于I/O操作而受阻塞。

  另一个更高优先级的线程出现。

  在支持时间片的系统中,该线程的时间片用完。


1、sleep()

使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据。注意该方法要捕捉异常。

例如有两个线程同时执行(没有synchronized)一个线程优先级为MAX_PRIORITY,另一个为MIN_PRIORITY,如果没有Sleep()方法,只有高优先级的线程执行完毕后,低优先级的线程才能够执行;但是高优先级的线程sleep(500)后,低优先级就有机会执行了。

总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。


2、join()

join()方法使调用该方法的线程在此之前执行完毕,也就是等待该方法的线程执行完毕后再往下继续执行。注意该方法也需要捕捉异常。

 

3、yield()

该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。

 

4、wait()和notify()、notifyAll()

 

这三个方法用于协调多个线程对共享数据的存取,所以必须在synchronized语句块内使用。synchronized关键字用于保护共享数据,阻止其他线程对共享数据的存取,但是这样程序的流程就很不灵活了,如何才能在当前线程还没退出synchronized数据块时让其他线程也有机会访问共享数据呢?此时就用这三个方法来灵活控制。

wait()方法使当前线程暂停执行并释放对象锁标示,让其他线程可以进入synchronized数据块,当前线程被放入对象等待池中。当调用notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。

notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。

注意 这三个方法都是java.lang.Object的方法。



二、run和start()

把需要处理的代码放到run()方法中,start()方法启动线程将自动调用run()方法,这个由java的内存机制规定的。并且run()方法必需是public访问权限,返回值类型为void。


三、关键字synchronized

该关键字用于保护共享数据,当然前提条件是要分清哪些数据是共享数据。每个对象都有一个锁标志,当一个线程访问到该对象,被Synchronized修饰的数据将被"上锁",阻止其他线程访问。当前线程访问完这部分数据后释放锁标志,其他线程就可以访问了。



四、wait()和notify(),notifyAll()是Object类的方法,sleep()和yield()是Thread类的方法。

(1)、常用的wait方法有wait()和wait(long timeout);

void wait() 在其他线程调用此对象的 notify() 方法或者 notifyAll()方法前,导致当前线程等待。

void wait(long timeout)在其他线程调用此对象的notify() 方法 或者 notifyAll()方法,或者超过指定的时间量前,导致当前线程等待。

wait()后,线程会释放掉它所占有的“锁标志”,从而使线程所在对象中的其他shnchronized数据可被别的线程使用。


wait()h和notify()因为会对对象的“锁标志”进行操作,所以他们必需在Synchronized函数或者 synchronized block 中进行调用。如果在non-synchronized 函数或 non-synchronized block 中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。。


(2)、Thread.sleep(long millis)必须带有一个时间参数。

sleep(long)使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会被执行;

sleep(long)可使优先级低的线程得到执行的机会,当然也可以让同优先级的线程有执行的机会;

sleep(long)是不会释放锁标志的。


(3)、yield()没有参数

sleep 方法使当前运行中的线程睡眠一段时间,进入不可以运行状态,这段时间的长短是由程序设定的,yield方法使当前线程让出CPU占有权,但让出的时间是不可设定的。

yield()也不会释放锁标志。

实际上,yield()方法对应了如下操作;先检测当前是否有相同优先级的线程处于同可运行状态,如有,则把CPU的占有权交给次线程,否则继续运行原来的线程,所以yield()方法称为“退让”,它把运行机会让给了同等级的其他线程。


sleep 方法允许较低优先级的线程获得运行机会,但yield()方法执行时,当前线程仍处在可运行状态,所以不可能让出较低优先级的线程此时获取CPU占有权。在一个运行系统中,如果较高优先级的线程没有调用sleep方法,也没有受到I/O阻塞,那么较低优先级线程只能等待所有较高优先级的线程运行结束,方可有机会运行。


yield()只是使当前线程重新回到可执行状态,所有执行yield()的线程有可能在进入到可执行状态后马上又被执行,所以yield()方法只能使同优先级的线程有执行的机会。


Java多线程的同步:synchronized关键字、Lock接口、volatile关键字 Java 多线程同步是解决资源共享冲突的核心机制,主要通过协调线程对共享资源的访问顺序与权限,避免数据不一致和竞态条件。在多线程的环境中,经常会碰到数据的共享问题,即当多线程需要访问同一个资源时,它们需要以某种顺序来确保该资源在某一时刻只能被一个线程使用,否则,程序的运行结果将会是不可预料的,在这种情况下就必须对数据进行同步。例如多个线程同时对同一数据进行写操作。 阅读详情

相关推荐

ORB_SLAM2 源码解析 多线程架构与数据流剖析(一)

本文深入解析ORB_SLAM2的多线程架构与数据流设计,详细剖析了Tracking、LocalMapping和LoopClosing三个核心线程的协作机制与生命周期管理。通过源码分析揭示了关键帧流转路径、线程同步锁机制及性能调优技巧,为开发者理解SLAM系统实时优化提供了实践指导。

weixin_42533751的博客 201

Java之线程礼让(yield方法)详解

yield() 方法尝试减少当前线程的运行时间片,从而给予同优先级的其他线程执行的机会。当一个线程调用 yield() 方法时,它表明自己愿意暂停执行,让出CPU给具有相同优先级的线程。然而,这种行为并不是强制性的,取决于操作系统的线程调度器是否接受这个建议。(1)当一个线程完成了大量的工作并且预计会有短暂的空闲期,可以调用 yield() 方法来允许其他线程执行,以提高整体的并发性能。在Java中,Thread 类的 yield() 方法是一个用于线程调度的方法,源码如下。

Lyhdreamer的博客 2174

多线程基础:创建与启动线程,线程的生命周期!

Java多线程的引入使得我们能够充分利用现代多核CPU的性能,同时让程序能够同时执行多个任务。在多线程编程中,理解线程的生命周期、线程的创建和启动方式,以及如何正确管理线程的执行,是构建高效多线程程序的基础。Java中的多线程编程为我们提供了强大的并发执行能力,理解线程的生命周期、如何创建和启动线程、以及如何管理线程的状态对于构建高效、稳定的应用程序至关重要。通过继承Thread类或实现Runnable接口,我们可以轻松地创建和启动线程。

喵手的博客 737

java之yield(),sleep(),wait()区别详解-备忘笔记

1、sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据。注意该方法要捕捉异常。 例如有两个线程同时执行(没有synchronized)一个线程优先级为MAX_PRIORITY,另一个为MIN_PRIORITY,如果没有Sleep()方法,只有高优先级的线程...

攻城师 3460

Java yield()线程让步实现过程解析

主要介绍了Java yield()线程让步实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

SAP中错记虚拟利润中心的调整,冲销处理实例

我非CO专业顾问。工作中遇到的问题,也会找资料,分析,测试。有时这个过程会拿到结果,解决问题。遂将过程记录下来备查。读者请谨慎参考!EC-PCA: 利润中心记账流程_9ke0-优快云博客。

专注SAP应用技术文章写作,致力于拉近用户与系统间的距离; 1795

java多线程回顾2:生命周期与控制

1、 线程生命周期概述 线程的生命周期如下图: 2、 新建与就绪 当程序使用new关键字创建一个线程之后,线程就处于新建状态了。此时线程只是被分配了内存资源,初始化了成员变量。 当线程对象被调用了start()方法之后,该线程就处于就绪状态了。表示这个线程可以运行但还没有运行,至于线程何时开始运行,取决于jvm的线程调度器。 有一点值得注意,启动线程应该使用st...

weixin_30824277的博客 76

【可信数据空间-部署方案】

此部署架构体现了以下几个核心原则:去中心化: 数据存储和处理完全分布在各个参与者端,运营方只提供核心的协调和信任基础设施。安全边界清晰: 通过VPC、DMZ、防火墙、K8s命名空间等技术,在每个层级都建立了严格的安全边界。高可用与弹性: 所有关键服务均以集群方式部署,避免单点故障,并能根据负载动态伸缩。云原生: 全面采用容器化和Kubernetes编排,简化部署、管理和运维复杂度。合规性: 架构设计天然满足数据驻留要求(数据留在企业本地),并为所有操作提供不可篡改的审计追踪能力。

u014716614的博客 771

Python多线程-如何停止循环线程?

三个解决方案 1.螺纹可停止功能 可以将函数修改为允许以下操作,而不是将threading.Thread分为子类:停下一个标志。 我们需要一个运行函数可访问的对象,将标志设置为停止运行。 我们可以使用doit对象。 import threading import time def doit(arg): t = threading.currentThread() while getattr(t, "do_run", True): print ("working on %s"

Best_307的博客 4819

智能座舱架构与芯片- (10) 音频篇 下

若将有限个 量化样值的绝对值从小到大依次排列,并对应地依次赋予一个十进制数字代码(例如,赋予样值0的十进制数字代码为0),在码前以“+”、“-”号为前缀,来 区分样值的正、负,则量化后的抽样信号就转化为按抽样时序排列的一串十进制数字码流,即十进制数字信号。如果声学密封不牢,来自内部结构的噪声可能到达传感器,两个传感器之间的泄漏可能降低BF算法的性能。未来,随着汽车电动化的普及,传统的ANC降噪所针对的发动机噪音已经不复存在,而路噪问题将越发明显,因此,全新的RNC主动路噪消减技术将会有一个更为宽广的市场。

joanna_xiao的博客 3838

告别蓝牙音质妥协:用ESP32和PCM5102搭建WiFi无损音频播放器(附完整代码)

本文详细介绍了如何利用ESP32微控制器和PCM5102 DAC芯片构建一套完整的WiFi无损音频流媒体系统,彻底摆脱蓝牙协议的音质束缚。从硬件原理到软件实现,包括核心器件选型、电路设计、I2S音频驱动实现以及系统优化方案,帮助音频发烧友实现高保真无线音频传输。

weixin_30733003的博客 541

线程的生命周期以及控制线程

一、线程的生命周期 线程状态转换图: 1、新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)。 注意:不能对已经启动的线程再次调用start()方法,否则会出现java.lang.IllegalThreadStateExcep

阎魔爱的博客 5542

Python爬虫实战:高效爬取中国版权登记数据

本文将详细介绍如何使用Python最新技术栈构建一个高效、稳定的中国版权登记数据爬虫系统。我们将使用Playwright+Asyncio实现无头浏览器自动化,结合Redis分布式任务队列和MongoDB数据存储,打造一个能够应对反爬机制的企业级数据采集方案。文章包含完整代码实现、性能优化技巧以及法律合规建议,帮助开发者快速掌握大规模数据采集的核心技术。本文详细介绍了2024年使用Python最新技术栈构建中国版权登记数据爬虫的完整方案。基于Playwright的无头浏览器自动化。

2201_76125261的博客 1897

线程的生命周期和状态控制

2、使用sleep后,线程进入阻塞状态,睡眠时间过后才会重新进入就绪状态,但从就绪状态到运行状态是由系统决定的,我们不能精准控制,所以调用Thread.sleep(1000)使得线程睡眠1秒,可能结果会大于1秒。1、sleep是静态方法,最好不要用Thread的实例对象调用它,因为它睡眠的始终是当前正在运行的线程,而不是调用它的线程对象,它只对正在运行状态的线程对象有效。线程的合并就是:线程A在运行期间,可以调用线程B的join()方法,这样线程A就必须等待线程B执行完毕后,才能继续执行。

kwjgi的博客 1747

【问题解决】Python 异步 asyncio 卡死、协程不执行、任务泄漏,保姆级排错

本文详细分析了Python异步编程中常见的卡死、协程不执行和任务泄漏问题。文章首先列举了这些问题的典型表现,如程序卡住、死锁、任务未启动等。然后深入剖析了各类问题的根源,包括同步阻塞操作、未正确await、资源未清理等。针对这些问题,文章提供了两套解决方案:一是异步编程最佳实践,包括安全协程执行、带超时的执行、任务清理等实用方法;二是死锁检测和预防机制,通过锁管理和等待图分析来避免死锁。文章还包含可直接使用的代码示例,帮助开发者快速定位和解决异步编程中的常见问题。

博客 448

uniapp微信小程序开发:解决Video播放m3u8视频流非卡顿问题,使用video视频标签播放M3U8视频流或直播流总是加载一卡一卡的体验非常差的情况【多种优化方案提升流畅度和缓冲方案示例源码】

uniapp微信小程序video播放m3u8视频流卡,uniapp video在微信小程序播放m3u8格式视频总是加载频繁卡顿,Uniapp微信小程序苹果ios真机播放m3u8很卡加载不流畅怎么办,uni-App如何解决小程序端video播放视频流M3U8格式出现卡顿情况,uniapp播放m3u8直播流卡顿如何优化?uniapp m3u8格式视频加载,.m3u8监控视频,uniapp微信小程序使用video组件播放M3U8视频卡顿,uniapp微信小程序视频播放卡顿如何解决,uniapp 打包微信小程序播放

✅ 精选推荐文章 2987

线程的生命周期与线程控制

线程的生命周期包括5中状态: 1、新生状态:用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态。 2、就绪:处于就绪状态的线程已经具备了运行条件,但需要进入线程队列,等待系统为其分配CPU,创建新线程有两种方式,这里是实现Runnable接口,下面有例子。 3、运行:在运行状态的线程执行自...

幽香飞狐的博客 392

3D 结构光相机工作原理全解 | 从编码投射到三维重建,原理 + 代码 + 工业实战一站式掌握

本文从3D结构光相机的整体架构出发,层层拆解了编码投射、相位计算、相位解包裹、三维重建的核心原理,补充了工业实战所需的公式推导、代码实现、参数调优、设备选型和案例落地,核心总结如下:相位是3D结构光成像的“灵魂”,其精度、稳定性直接决定3D重建的效果,包裹相位与绝对相位的区分的是工业实战的基础;编码投射的核心是“正弦条纹+格雷码条纹”组合,正弦条纹负责高精度相位提取,格雷码条纹辅助解包裹,适配工业场景的精度与稳定性需求;

getusushu的博客 411

Java并发编程(三、java线程的生命周期与状态控制)

线程的生命周期,就是一个线程从创建到消亡的过程。当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)五种不同的状态。尤其是当线程启动以后,它不可能一直“霸占”着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换。创建Thread类的实例成功后,则该线程对象就处于新建状态。

sinat_42333476的博客 2002

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Java 多线程基础:彻底搞懂进程与线程的区别及线程生命周期

本文深入浅出地讲解了Java多线程的核心概念。首先通过生活场景类比,说明进程和线程的区别:进程是独立资源分配单位,线程是轻量执行单元,共享进程资源。文章从资源占有、开销、独立性三个维度对比分析,并形象比喻为;独立豪宅;和;共享公寓;。接着详细解析线程生命周期的5种状态(新建、就绪、运行、阻塞、终止)及其转换条件,配合代码示例验证状态转换。最后强调理解这些基础概念对排查线程问题的重要性,为后续学习线程同步、线程池等内容奠定基础。

qq_40303030的博客 1582

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

98. 线程生命周期

Java线程生命周期包括6种状态:NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(无限等待)、TIMED_WAITING(超时等待)和TERMINATED(终止)。NEW是初始状态,需调用start()进入RUNNABLE状态;RUNNABLE表示线程就绪或运行中,可能等待CPU资源;BLOCKED是等待锁的状态;WAITING和TIMED_WAITING是主动等待状态;TERMINATED是终止状态。线程状态转换受JVM和操作系统共同管理,主流实现采用1:1线程模型。

weixin_43484713的博客 838

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

线程生命周期以及线程创建的三种方式

1. 线程生命周期 线程生命周期图 新建状态(New) 当线程对象创建后,即进入新建状态,如:Thread t = new MyThread(); 就绪状态(Runnable) 当调用线程对象的start()方法时,线程即进入就绪状态。处于就绪状态的线程只是说明此线程已经做好准备,随时等待CPU调度执行,并不是说执行了start()方法就立即执行。 运行状态(Running) 当CP...

钱立清的博客 4857

Java 线程的奇妙之旅:深度解析生命周期与状态

在Java多线程编程中,理解线程的生命周期和状态是开发高效并发程序的基础。线程作为操作系统调度的基本单位,其状态变化直接影响程序的执行效率和资源管理

qq_17153885的博客 1041

线程的生命周期

一、概述 线程的生命周期包含5个阶段,包括:新建、就绪、运行、阻塞、死亡。 当线程进入运行状态后,一般的操作系统是采用抢占式的方式来让线程获得CPU。所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞、就绪之间切换。 二、新建 新建:使用new方法,new出来线程,此时仅仅由JAVA虚拟机为其分配内存,并初始化成员变量的值。此时仅仅是个对象。 三、就绪 就绪:就是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行; 该线程进入就绪状态,JA

liwangcuihua的博客 1万+

Java 并发编程通关秘籍——02线程的生命周期与状态控制

Java 线程的生命周期包含 6 种状态,这些状态可通过Thread.State枚举类型获取,它们在程序运行过程中相互转换,构成了线程完整的生命周期。

qq_60626054的博客 684

Java多线程——线程的生命周期和状态控制

Java多线程——线程的生命周期和状态控制 一、线程的生命周期 线程状态转换图: 1、新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)。 注意:不能对已经启动的线程再次调用start()方法,否则会出现java.lang.IllegalThreadSta...

qq_35222843的博客 482
上一篇: 线程1:线程的创建和启动
下一篇: 线程3:线程同步
王小禾
博客等级 码龄11年 80粉丝 291原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值