当前位置: 首页 > news >正文

Java并发编程

进程和线程

进程即程序的一次执行过程,各个进程之间是独立的。线程是更小的单位,一次进程中,可能会有多个线程,可能会相互影响,各个线程有自己的程序计数器,虚拟机栈和本地方法栈,同时共同使用堆和方法区资源

线程的生命周期和状态

NEW:线程被创建出来,但是未调用start()方法

RUNNABLE:线程调用了start()方法

BLOCKED:等待锁释放

WAITING:线程调用Object.wait()、Thread.join()或LockSupport.park()方法时,进入等待状态

TIME_WAITING:线程调用Thread.sleep()、Object.wait()或Thread.join()方法时,带有超时时间参数,进入计时等待状态。

TERMINATED:当线程执行完它的任务或发生异常时,它进入终止状态。

线程上下文切换

线程执行过程时有自己的运行状态(称作上下文),如程序计数器等信息,退出cpu状态,加载另一个cpu的上下文。

发生切换时机

主动让出cpu,调用sleep()或wait()方法

时间片用完

被终止或结束运行

死锁

什么是死锁

多个线程同时阻塞,互相等待对象释放资源

死锁产生条件

互斥条件:同一个资源在同一时刻只能被一个线程占有

不可剥夺条件:一个线程持有资源时,不能被其他线程剥夺

请求与保持条件:一个线程因请求资源阻塞时,会继续占用已有的资源

循环等待条件:若干线程形成首尾相接的循环等待关系

如果避免死锁

破坏不可剥夺条件:线程可以剥夺其他线程占用的资源

破坏请求与保持条件:一次性申请所有资源

破坏循环等待条件:按序申请资源,反序释放资源

wait和sleep方法

sleep()方法不会释放对象锁。当一个线程调用sleep()方法时,它会让当前线程休眠一段时间,但是它并不会释放对象锁。其他线程仍然无法获取该对象的锁。

wait()方法会释放对象锁。当一个线程调用wait()方法时,它会让当前线程等待,并释放对象锁,以便其他线程可以获取该对象的锁并执行。

sleep是Thread类的方法,而wait是Objec类的方法.

代码示例

public static void main(String[] args) {final Object lock = new Object();Thread waitingThread = new Thread(() -> {synchronized (lock) {System.out.println(LocalTime.now() +  " " + Thread.currentThread().getName()   +  " Waiting thread is running");try {lock.wait();     // 线程等待,释放对象锁} catch (InterruptedException e) {e.printStackTrace();}System.out.println(LocalTime.now() +  " " + Thread.currentThread().getName()   +  " Waiting thread is done");}});Thread notifyingThread = new Thread(() -> {synchronized (lock) {try {Thread.sleep(1000);   //休眠1s} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(LocalTime.now() +  " " + Thread.currentThread().getName()   +  " Notifying thread is running");lock.notify(); // 唤醒等待中的线程System.out.println(LocalTime.now() +  " " + Thread.currentThread().getName()   +  " Notifying thread is done");}});waitingThread.start();notifyingThread.start();}

 输出结果

15:36:44.350 Thread-0 Waiting thread is running
15:36:45.352 Thread-1 Notifying thread is running
15:36:45.352 Thread-1 Notifying thread is done
15:36:45.352 Thread-0 Waiting thread is done

Synchronized

原理

每个对象都有一个与之关联的监视器(monitor),当一个线程进入一个对象的 synchronized 方法或代码块时,它会尝试获取这个对象的内置锁。如果这个锁已经被其他线程获取了,那么当前线程将被阻塞,直到获取到这个锁为止。

当一个线程获取到对象的内置锁后,它就可以执行 synchronized 方法或代码块中的操作。在执行完这些操作后,线程会释放对象的内置锁,这样其他线程就有机会获取到这个锁,

ReentrantLock

原理

ReentrantLock 是通过 lock() 和 unlock() 方法来实现锁的获取和释放,支持可重入特性和公平性选择,同时还提供了条件变量的支持。其底层实现是基于 AQS 框架的,通过这些机制来实现多线程的同步和互斥操作。

Synchronized和ReentrantLock比较

相同点:可重入,

区别:synchronized依赖JVM,而ReetranLock依赖API;

ReentrantLock实现等待可中断,公平锁,选择通知

http://www.lryc.cn/news/250638.html

相关文章:

  • vue+echarts实现依赖关系无向网络拓扑结图节点折叠展开策略
  • Unity3d 灯光阴影开启,法线贴图出现BUG
  • c语言:模拟实现atoi函数
  • Docker 使用心得
  • Nacos 架构原理
  • 尝试修改vim光标的思路
  • SpringBoot整合Activiti7——消息事件(十)
  • 高翔:《自动驾驶与机器人中的SLAM技术 》-Slam_in_autonomous_driving 编译过程中遇到的问题
  • org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder 实现密码加密 验证 代码示例
  • 《微信小程序开发从入门到实战》学习三十八
  • 云服务器哪家便宜?亚马逊AWS等免费云服务器推荐
  • Linux删除了大文件为什么磁盘空间没有释放?
  • 编写bat脚本执行msyql建库sql
  • 【JavaSE学习专栏】第04篇 Java面向对象
  • sCrypt 在英国伦敦 Exeter 大学讲学
  • 人工智能基础创新的第二增长曲线
  • 华为OD机试真题-分割均衡字符串-2023年OD统一考试(C卷)
  • 基于SpringBoot的图书推荐系统的
  • 02_学习使用javax_ws_rs_下载文件
  • js校验多个时间段的时间是否有交叉
  • Python Spyder开发的应用项目
  • ES6知识点
  • 数据结构详解各种算法
  • Qt实现右键菜单
  • MySQL基础篇一
  • 深入了解Java8新特性-日期时间API:OffsetDateTime类
  • 企业微信http协议接口开发,发送位置消息
  • CSS——基础选择器、文字控制属性
  • 08-中介者模式-C语言实现
  • 【开源】基于JAVA的医院门诊预约挂号系统