Java中的线程

本文详细解析了Java线程的基本概念,包括Runnable接口的使用、守护线程的特点、原子性和易变性的理解、原子操作的实现方式、线程中断机制以及yield和sleep方法的区别。深入探讨了线程在并发编程中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程任务

Runnable接口定义了任务,但若想实现线程行为,必须将任务附着在线程上,因此创建线程Thread并将一个Runnable对象交给该线程,启动Threadstart对象将为该线程执行必须的初始化操作,并调用Runnable对象的run方法执行任务。

守护线程

Daemon线程在后台提供服务,也称后台线程。当所有非后台线程结束时,程序结束,所有后台线程会被即刻终止,因此若在后台线程的代码中添加finally想要优雅的关闭后台线程是无法实现的。
后台线程的设置setDaemon()必须在线程启动前设置,在后台线程中创建的线程也会默认为后台线程

原子性和易变性

对于除了longdouble类型,其他基本类型的简单操作(读取、写入)都是原子性的,因为longdouble类型占了8个字节64bit,会造成字节撕裂,即32位操作系统会对64位的的读取写入分成两个32位的读取写入,造成问题。
volatile保证可见性和有序性但无法保证原子性,具体原因看我这篇博文

原子操作

java通过锁和循环CAS实现原子操作
通过自旋循环CAS直到成功,但CAS仍存在三大问题:

  1. ABA。即原值从A改变成B又变成A,使用CAS以为没有变化,实际变化了。解决思路为增加版本号。
  2. 循环时间长开销大。如果长时间不成功,会给CPU造成很大开销。
  3. 只能保证一个共享变量的原子操作。解决方案是使用锁或将多个共享变量合并成一个共享变量。

线程中断

中断只是设置中断标志位,能够进入到catch中断异常处理语句,但不是说线程就到此终结了,若在catch中设置了return,则返回到方法入口,方法消亡。否则继续往下执行。若先中断后面遇到sleep,则立即抛出中断异常,并将中断标志清空。

yield()

sleep() 方法使当前运行中的线程睡眠一段时间,进入不可以运行状态,这段时间的长短是由程序设定的,sleep() 方法允许较低优先级的线程获得运行机会
yield()方法使当前线程让出CPU占有权,但让出的时间是不可设定的,也不会释放锁标志。yield()只是使当前线程重新回到可执行状态,所有执行yield()的线程有可能在进入到可执行状态后马上又被执行,所以yield()方法只能使同优先级的线程有执行的机会,在一个运行系统中,如果较高优先级的线程没有调用sleep()方法,也没有受到I/O阻塞,那么较低优先级线程只能等待所有较高优先级的线程运行结束,方可有机会运行。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值