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

Java笔记(死锁、线程通信、单例模式)

一、死锁

1.概述

  • 死锁 : 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法往下执行。
  • 此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程
  • 原理 :
    1. 某个线程执行完成,需要先后嵌套锁定两个对象,在这个过程中,先锁定了第一个对象
    2. 另一个线程执行完成也需要先后嵌套锁定两个对象,在这个过程中,先锁定了第二个对象
    3. 第一个线程执行中,要执行到第二个对象的时候,发现第二个对象被锁定,进入等待状态,等待交出锁
    4. 第二个线程执行中,要执行到第一个对象的时候,发现第一个对象也被锁定,也进入等待状态
    5. 此时两个线程都在等待对方交出锁,导致死锁

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;}
}

四、线程池

  • 线程池的作用:
    • 线程池作用就是限制系统中执行线程的数量。
  • 根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;
  • 少了浪费了系统资源,多了造成系统拥挤效率不高。
  • 用线程池控制线程数量,其他线程排队等候。
  • 一个任务执行完毕,再从队列的中取最前面的任务开始执行。
  • 若队列中没有等待进程,线程池的这一资源处于等待。
  • 当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了,否则进入等待队列。
  • 为什么要用线程池:
    1. 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。
    2. 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)

相关文章:

Java笔记(死锁、线程通信、单例模式)

一、死锁 1.概述 死锁 : 死锁是指两个或两个以上的进程在执行过程中&#xff0c;由于竞争资源或者由于彼此通信而造成的一种阻塞的现象&#xff0c;若无外力作用&#xff0c;它们都将无法往下执行。此时称系统处于死锁状态或系统产生了死锁&#xff0c;这些永远在互相等待的进…...

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服务端参数配置 消息的发送与接收 生产者 生产者主要的对象有&#xff1a; KafkaProducer &#xff0c; ProducerRecord 。 其中 KafkaProducer 是用于发送消息的类&#xff0c; ProducerRecord 类用于封装Kafka的消息…...

【C语言】(1)初识C语言

什么是C语言 C语言是一种广泛应用的计算机编程语言&#xff0c;它具有强大的功能和灵活性&#xff0c;使其成为系统编程和底层开发的首选语言。C语言的设计简洁、高效&#xff0c;且不依赖于特定的硬件或系统&#xff0c;因此在各种计算平台上都能稳定运行。 C语言的特点 高…...

SpringCloudStream整合MQ(待完善)

概念 Spring Cloud Stream 的主要目标是各种各样MQ的学习成本&#xff0c;提供一致性的编程模型&#xff0c;使得开发者能够更容易地集成消息组件&#xff08;如 Apache Kafka、RabbitMQ、RocketMQ&#xff09; 官网地址&#xff1a;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名称哪些事&#xff08;20240125&#xff09;1 问题2 排查3 扩展总结 第139期 做大还是做小-Oracle名称哪些事&#xff08;20240125&#xff09; 作者&#xff1a;胖头鱼的鱼缸&#xff08;尹海文&#xff09; Oracle A…...

驱动开发--多路复用-信号

一、多路复用 每个进程都有一个描述符数组&#xff0c;这个数组的下标为描述符&#xff0c; 描述符的分类&#xff1a; 文件描述符&#xff1a;设备文件、管道文件 socket描述符 1.1 应用层&#xff1a;三套接口select、poll、epoll select&#xff1a;位运算实现 监控的描…...

LeetCode 2859. 计算 K 置位下标对应元素的和【位操作】1000

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…...

composer安装hyperf后,nginx配置hyperf

背景 引入hyperf项目用作微服务&#xff0c;使用composer 安装hyperf后&#xff0c;对hyperf进行nginx配置。 配置步骤 因为hyperf监听的是端口&#xff0c;不像其他laravel、lumen直接指向文件即可。所有要监听端口号。 1 配置nginx server {listen 80;//http&#xff1a…...

Flink对接Kafka的topic数据消费offset设置参数

scan.startup.mode 是 Flink 中用于设置消费 Kafka topic 数据的起始 offset 的配置参数之一。 scan.startup.mode 可以设置为以下几种模式&#xff1a; earliest-offset&#xff1a;从最早的 offset 开始消费数据。latest-offset&#xff1a;从最新的 offset 开始消费数据。…...

TryHackMe-Umbrella

靶场介绍 Breach Umbrella Corp’s time-tracking server by exploiting misconfigurations around containerisation. 利用集装箱化的错误配置&#xff0c;破坏Umbrella公司的时间跟踪服务器。 Task 1 What is the DB password? 数据库的密码是多少&#xff1f; 端口扫描&am…...

Excel导出警告:文件格式和拓展名不匹配

原因描述&#xff1a; Content-Type 原因&#xff1a;Content-Type&#xff0c;即内容类型&#xff0c;一般是指网页中存在的Content-Type&#xff0c;用于定义网络文件的类型和网页的编码&#xff0c;决定文件接收方将以什么形式、什么编码读取这个文件&#xff0c;这就是经常…...

kafka集群和Filebeat+Kafka+ELK

一、Kafka 概述 1.1 为什么需要消息队列&#xff08;MQ&#xff09; 主要原因是由于在高并发环境下&#xff0c;同步请求来不及处理&#xff0c;请求往往会发生阻塞。比如大量的请求并发访问数据库&#xff0c;导致行锁表锁&#xff0c;最后请求线程会堆积过多&#xff0c;从…...

golang map真有那么随机吗?——map遍历研究

在随机选取map中元素时&#xff0c;本想用map遍历的方式来返回&#xff0c;但是却并没有通过测试。 那么难道map的遍历并不是那么的随机吗&#xff1f; 以下代码参考go1.18 hiter是map遍历的结构&#xff0c;主要记录了当前遍历的元素、开始位置等来完成整个遍历过程 // A ha…...

详细分析对比copliot和ChatGPT的差异

Copilot 和 ChatGPT 是两种不同的AI工具&#xff0c;分别在不同领域展现出了强大的功能和潜力&#xff1a; GitHub Copilot 定位与用途&#xff1a;GitHub Copilot 是由GitHub&#xff08;现为微软子公司&#xff09;和OpenAI合作开发的一款智能代码辅助工具。它主要集成于Visu…...

TENT:熵最小化的Fully Test-Time Adaption

摘要 在测试期间&#xff0c;模型必须自我调整以适应新的和不同的数据。在这种完全自适应测试时间的设置中&#xff0c;模型只有测试数据和它自己的参数。我们建议通过test entropy minimization (tent[1])来适应:我们通过其预测的熵来优化模型的置信度。我们的方法估计归一化…...

研发日记,Matlab/Simulink避坑指南(五)——CAN解包 DLC Bug

文章目录 前言 背景介绍 问题描述 分析排查 解决方案 总结 前言 见《研发日记&#xff0c;Matlab/Simulink避坑指南&#xff08;一&#xff09;——Data Store Memory模块执行时序Bug》 见《研发日记&#xff0c;Matlab/Simulink避坑指南(二)——非对称数据溢出Bug》 见《…...

机器人3D视觉引导半导体塑封上下料

半导体塑封上下料是封装工艺中的重要环节&#xff0c;直接影响到产品的质量和性能。而3D视觉引导技术的引入&#xff0c;使得这一过程更加高效、精准。它不仅提升了生产效率&#xff0c;减少了人工操作的误差&#xff0c;还为半导体封装技术的智能化升级奠定了坚实的基础。 传统…...

(十二)Head first design patterns代理模式(c++)

代理模式 代理模式&#xff1a;创建一个proxy对象&#xff0c;并为这个对象提供替身或者占位符以对这个对象进行控制。 典型例子&#xff1a;智能指针... 例子&#xff1a;比如说有一个talk接口&#xff0c;所有的people需要实现talk接口。但有些人有唱歌技能。不能在talk接…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...