Java笔记(死锁、线程通信、单例模式)
一、死锁
1.概述
- 死锁 : 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法往下执行。
- 此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程
- 原理 :
-
- 某个线程执行完成,需要先后嵌套锁定两个对象,在这个过程中,先锁定了第一个对象
- 另一个线程执行完成也需要先后嵌套锁定两个对象,在这个过程中,先锁定了第二个对象
- 第一个线程执行中,要执行到第二个对象的时候,发现第二个对象被锁定,进入等待状态,等待交出锁
- 第二个线程执行中,要执行到第一个对象的时候,发现第一个对象也被锁定,也进入等待状态
- 此时两个线程都在等待对方交出锁,导致死锁
2.代码实现
public class Thread_01_DeadLock {public static void main(String[] args) {Object o1=new Object();Object o2=new Object();Thread t1=new Thread(new T1(o1, o2));Thread t2=new Thread(new T2(o1, o2));t1.start();t2.start();}
}
class T1 implements Runnable{Object o1;Object o2;public T1(Object o1,Object o2){this.o1=o1;this.o2=o2;}@Overridepublic void run() {synchronized (o1) {
// try {//加上睡眠一定死锁
// Thread.sleep(1000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }System.out.println(Thread.currentThread().getName()+"-->T1o1已锁定");synchronized (o2) {System.out.println(Thread.currentThread().getName()+"-->T1o2已锁定");}}System.out.println("t1执行完成");}
}
class T2 implements Runnable{Object o1;Object o2;public T2(Object o1,Object o2){this.o1=o1;this.o2=o2;}@Overridepublic void run() {try {//加上睡眠一定不死锁Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (o2) {System.out.println(Thread.currentThread().getName()+"-->T2o2已锁定");synchronized (o1) {System.out.println(Thread.currentThread().getName()+"-->T2o1已锁定");}}System.out.println("t2执行完成");}
}
二、线程通信
1.概述
- Object中的方法
- wait : 让当前线程进入等待状态(挂起),并释放锁,当被唤醒之后,接着挂起的位置继续执行,假如之前执行了1、2,到3挂起,那么被唤醒后接着执行3
- notify : 唤醒一个在该对象中挂起的任意一个线程
- notifyAll : 唤醒在该对象中挂起的所有线程
- 这几个方法必须出现在加锁的成员方法中
- wait : 如果是无参,则不会自动醒,也可以传入long类型的值,代表毫秒数,多久之后自动醒
- wait 和 sleep的区别 :
-
- sleep : 让当前线程进入睡眠状态, 是静态方法,和是否加锁没有关系,如果在加锁的方法中,也不会释放锁
- wait : 让当前线程进入挂起等待状态,必须在加锁的成员方法中,另外会释放锁
2.使用方式
public class Thread_03_Wait {public static void main(String[] args) throws InterruptedException {Num num=new Num();Thread t1=new PrintNum(num);Thread t2=new PrintNum(num);t1.start();Thread.sleep(10);//保证t1先执行t2.start();}
}
class PrintNum extends Thread{Num num;public PrintNum(Num num){this.num=num;}@Overridepublic void run() {while (true) {num.printNums();}}
}
class Num{private int count =1;public synchronized void printNums(){System.out.println(Thread.currentThread().getName()+"-->"+count);count++;// 唤醒等待的进程this.notifyAll();try {Thread.sleep(1000);// 进入挂起状态,并释放锁this.wait();} catch (InterruptedException e) {e.printStackTrace();}}
}
3.生产者消费者

3.1.示例
public class Thread_04_Producer {public static void main(String[] args) {SynStack ss=new SynStack();Thread producer1=new Thread(new Producer(ss));Thread producer2=new Thread(new Producer(ss));Thread consumer1=new Thread(new Consumer(ss));Thread consumer2=new Thread(new Consumer(ss));producer1.start();producer2.start();consumer1.start();consumer2.start();}
}
class Producer implements Runnable{private SynStack ss;public Producer(SynStack ss){this.ss=ss;}@Overridepublic void run() {for (int i = 0; i < 26; i++) {ss.push((char)('a'+i));}}
}
class Consumer implements Runnable{private SynStack ss;public Consumer(SynStack ss){this.ss=ss;}@Overridepublic void run() {for (int i = 0; i < 26; i++) {ss.pop();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}
}
//业务类
class SynStack{int count=0;// 货物数量char[] data=new char[6];// 记录货物数量// 生产货物public synchronized void push(char ch){// 判断货物满没满while(count ==data.length){//try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//仓库空了该生产了,此时应该唤醒挂起的消费者if (count==0) {this.notifyAll();}data[count++]=ch;System.out.println(Thread.currentThread().getName()+"生产了 "+ch+" 还剩 "+count+" 个货物");}// 消费货物public synchronized char pop(){// 判断货物空没空while(count ==0){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//仓库满了该挂起了,此时应该唤醒挂起的生产者if (count==data.length) {this.notifyAll();}char ch=data[--count];System.out.println(Thread.currentThread().getName()+"消费了 "+ch+" 还剩 "+count+" 个货物");return ch;}
}
三、单例模式
public class SingLeton {private SingLeton(){}// volatile 防止指令重排private volatile static SingLeton singLeton;public static SingLeton getInstance(){// 多线程可能同时进入if (singLeton==null) {// 一个线程进入synchronized (SingLeton.class) {if (singLeton==null) {// 一个线程进入后 对象就不再是null,其他的线程将无法进入singLeton=new SingLeton();} }}return singLeton;}
}
四、线程池
- 线程池的作用:
-
- 线程池作用就是限制系统中执行线程的数量。
- 根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;
- 少了浪费了系统资源,多了造成系统拥挤效率不高。
- 用线程池控制线程数量,其他线程排队等候。
- 一个任务执行完毕,再从队列的中取最前面的任务开始执行。
- 若队列中没有等待进程,线程池的这一资源处于等待。
- 当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了,否则进入等待队列。
- 为什么要用线程池:
-
- 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
- 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)
相关文章:
Java笔记(死锁、线程通信、单例模式)
一、死锁 1.概述 死锁 : 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法往下执行。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进…...
DAY11_(简易版)VUEElement综合案例
目录 1 VUE1.1 概述1.1.1 Vue js文件下载 1.2 快速入门1.3 Vue 指令1.3.1 v-bind & v-model 指令1.3.2 v-on 指令1.3.3 条件判断指令1.3.4 v-for 指令 1.4 生命周期1.5 案例1.5.1 需求1.5.2 查询所有功能1.5.3 添加功能 2 Element2.0 element-ui js和css和字体图标下载2.1 …...
【Kafka】开发实战和Springboot集成kafka
目录 消息的发送与接收生产者消费者 SpringBoot 集成kafka服务端参数配置 消息的发送与接收 生产者 生产者主要的对象有: KafkaProducer , ProducerRecord 。 其中 KafkaProducer 是用于发送消息的类, ProducerRecord 类用于封装Kafka的消息…...
【C语言】(1)初识C语言
什么是C语言 C语言是一种广泛应用的计算机编程语言,它具有强大的功能和灵活性,使其成为系统编程和底层开发的首选语言。C语言的设计简洁、高效,且不依赖于特定的硬件或系统,因此在各种计算平台上都能稳定运行。 C语言的特点 高…...
SpringCloudStream整合MQ(待完善)
概念 Spring Cloud Stream 的主要目标是各种各样MQ的学习成本,提供一致性的编程模型,使得开发者能够更容易地集成消息组件(如 Apache Kafka、RabbitMQ、RocketMQ) 官网地址:Spring Cloud Stream 组件 1. Binder 2…...
【Java 数据结构】包装类简单认识泛型
包装类&简单认识泛型 1 包装类1.1 基本数据类型和对应的包装类1.2 装箱和拆箱1.3 自动装箱和自动拆箱 2 什么是泛型3 引出泛型3.1 语法 4 泛型类的使用4.1 语法4.2 示例4.3 类型推导(Type Inference) 5 泛型如何编译的5.1 擦除机制5.2 为什么不能实例化泛型类型数组 6 泛型…...
第139期 做大还是做小-Oracle名称哪些事(20240125)
数据库管理139期 2024-01-25 第139期 做大还是做小-Oracle名称哪些事(20240125)1 问题2 排查3 扩展总结 第139期 做大还是做小-Oracle名称哪些事(20240125) 作者:胖头鱼的鱼缸(尹海文) Oracle A…...
驱动开发--多路复用-信号
一、多路复用 每个进程都有一个描述符数组,这个数组的下标为描述符, 描述符的分类: 文件描述符:设备文件、管道文件 socket描述符 1.1 应用层:三套接口select、poll、epoll select:位运算实现 监控的描…...
LeetCode 2859. 计算 K 置位下标对应元素的和【位操作】1000
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
composer安装hyperf后,nginx配置hyperf
背景 引入hyperf项目用作微服务,使用composer 安装hyperf后,对hyperf进行nginx配置。 配置步骤 因为hyperf监听的是端口,不像其他laravel、lumen直接指向文件即可。所有要监听端口号。 1 配置nginx server {listen 80;//http:…...
Flink对接Kafka的topic数据消费offset设置参数
scan.startup.mode 是 Flink 中用于设置消费 Kafka topic 数据的起始 offset 的配置参数之一。 scan.startup.mode 可以设置为以下几种模式: earliest-offset:从最早的 offset 开始消费数据。latest-offset:从最新的 offset 开始消费数据。…...
TryHackMe-Umbrella
靶场介绍 Breach Umbrella Corp’s time-tracking server by exploiting misconfigurations around containerisation. 利用集装箱化的错误配置,破坏Umbrella公司的时间跟踪服务器。 Task 1 What is the DB password? 数据库的密码是多少? 端口扫描&am…...
Excel导出警告:文件格式和拓展名不匹配
原因描述: Content-Type 原因:Content-Type,即内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式、什么编码读取这个文件,这就是经常…...
kafka集群和Filebeat+Kafka+ELK
一、Kafka 概述 1.1 为什么需要消息队列(MQ) 主要原因是由于在高并发环境下,同步请求来不及处理,请求往往会发生阻塞。比如大量的请求并发访问数据库,导致行锁表锁,最后请求线程会堆积过多,从…...
golang map真有那么随机吗?——map遍历研究
在随机选取map中元素时,本想用map遍历的方式来返回,但是却并没有通过测试。 那么难道map的遍历并不是那么的随机吗? 以下代码参考go1.18 hiter是map遍历的结构,主要记录了当前遍历的元素、开始位置等来完成整个遍历过程 // A ha…...
详细分析对比copliot和ChatGPT的差异
Copilot 和 ChatGPT 是两种不同的AI工具,分别在不同领域展现出了强大的功能和潜力: GitHub Copilot 定位与用途:GitHub Copilot 是由GitHub(现为微软子公司)和OpenAI合作开发的一款智能代码辅助工具。它主要集成于Visu…...
TENT:熵最小化的Fully Test-Time Adaption
摘要 在测试期间,模型必须自我调整以适应新的和不同的数据。在这种完全自适应测试时间的设置中,模型只有测试数据和它自己的参数。我们建议通过test entropy minimization (tent[1])来适应:我们通过其预测的熵来优化模型的置信度。我们的方法估计归一化…...
研发日记,Matlab/Simulink避坑指南(五)——CAN解包 DLC Bug
文章目录 前言 背景介绍 问题描述 分析排查 解决方案 总结 前言 见《研发日记,Matlab/Simulink避坑指南(一)——Data Store Memory模块执行时序Bug》 见《研发日记,Matlab/Simulink避坑指南(二)——非对称数据溢出Bug》 见《…...
机器人3D视觉引导半导体塑封上下料
半导体塑封上下料是封装工艺中的重要环节,直接影响到产品的质量和性能。而3D视觉引导技术的引入,使得这一过程更加高效、精准。它不仅提升了生产效率,减少了人工操作的误差,还为半导体封装技术的智能化升级奠定了坚实的基础。 传统…...
(十二)Head first design patterns代理模式(c++)
代理模式 代理模式:创建一个proxy对象,并为这个对象提供替身或者占位符以对这个对象进行控制。 典型例子:智能指针... 例子:比如说有一个talk接口,所有的people需要实现talk接口。但有些人有唱歌技能。不能在talk接…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...
C++--string的模拟实现
一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现,其目的是加强对string的底层了解,以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量,…...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...
2025.6.9总结(利与弊)
凡事都有两面性。在大厂上班也不例外。今天找开发定位问题,从一个接口人不断溯源到另一个 接口人。有时候,不知道是谁的责任填。将工作内容分的很细,每个人负责其中的一小块。我清楚的意识到,自己就是个可以随时替换的螺丝钉&…...
【PX4飞控】mavros gps相关话题分析,经纬度海拔获取方法,卫星数锁定状态获取方法
使用 ROS1-Noetic 和 mavros v1.20.1, 携带经纬度海拔的话题主要有三个: /mavros/global_position/raw/fix/mavros/gpsstatus/gps1/raw/mavros/global_position/global 查看 mavros 源码,来分析他们的发布过程。发现前两个话题都对应了同一…...
CVE-2023-25194源码分析与漏洞复现(Kafka JNDI注入)
漏洞概述 漏洞名称:Apache Kafka Connect JNDI注入导致的远程代码执行漏洞 CVE编号:CVE-2023-25194 CVSS评分:8.8 影响版本:Apache Kafka 2.3.0 - 3.3.2 修复版本:≥ 3.4.0 漏洞类型:反序列化导致的远程代…...
