重学java 39.多线程 — 线程安全

逐渐成为一个情绪稳定且安静成长的人

                                                       ——24.5.24

线程安全

什么时候发生?

       当多个线程访问同一个资源时,导致了数据有问题,出现并发问题,数据不能及时更新,导致数据发生错误,出现线程安全问题

多线程安全问题示例

package S71ThreadSafe;public class MyTicket implements Runnable{// 定义100章票int ticket = 100;@Overridepublic void run(){while(true){if(ticket>0){System.out.println(Thread.currentThread().getName()+"买了第"+ticket+"张票");ticket--;}}}
}
package S71ThreadSafe;public class Demo210Test {public static void main(String[] args) {// new一次,分别传递到三个线程对象中去MyTicket myTicket = new MyTicket();Thread th1= new Thread(myTicket, "赵四");Thread th2= new Thread(myTicket, "刘能");Thread th3= new Thread(myTicket, "广坤");th1.start();th2.start();th3.start();}
}

解决线程安全问题方式一:同步代码块

synchronized代码块 == 上锁 可以解决线程安全问题,不保证线程顺序

1.格式:

        synchronized(任意接收对象){

               线程要执行的语句;

        }

2.任意对象:

        就是我们的锁对象

3.执行:

        一个线程拿到锁之后,会进入到同步代码块中执行,在此期间,其他线程拿不到锁,就进不去同步代码块。需要在同步代码块外面等待排队,需要等待执行的线程执行完毕,出了同步代码块,相当于释放锁了,等待的线程才能抢到锁,才能进入到同步代码块中执行,上的锁必须是同一个锁对象,同一把锁

package S71ThreadSafe;import java.util.Scanner;public class MyTicket implements Runnable{// 定义100章票int ticket = 100;// 任意new一个对象Object obj = new Object();Scanner sc = new Scanner(System.in);@Overridepublic void run(){while(true){synchronized (sc) {if (ticket > 0) {System.out.println(Thread.currentThread().getName() + "买了第" + ticket + "张票");ticket--;}}}}
}
package S71ThreadSafe;public class Demo210Test {public static void main(String[] args) {// new一次,分别传递到三个线程对象中去MyTicket myTicket = new MyTicket();Thread th1= new Thread(myTicket, "赵四");Thread th2= new Thread(myTicket, "刘能");Thread th3= new Thread(myTicket, "广坤");th1.start();th2.start();th3.start();}
}

解决线程安全问题方式二:同步方法

1.普通同步方法_非静态

        在普通方法内用一个同步代码块

① 格式:

        修饰符 synchronized 返回值类型 方法名(参数){

                方法体
                return 结果

        }

② 默认锁:

        this

package S73ThreadSafeSolve2;public class Demo212Test {public static void main(String[] args) {// new一次,分别传递到三个线程对象中去MyTicket myTicket = new MyTicket();System.out.println(myTicket);Thread th1= new Thread(myTicket, "赵四");Thread th2= new Thread(myTicket, "刘能");Thread th3= new Thread(myTicket, "广坤");th1.start();th2.start();th3.start();}
}
package S73ThreadSafeSolve2;import java.util.Scanner;public class MyTicket implements Runnable{// 定义100章票int ticket = 100;Scanner sc = new Scanner(System.in);@Overridepublic void run(){while(true){try{Thread.sleep(100L);} catch (InterruptedException e) {throw new RuntimeException(e);}// 调用同步方法// method01();method02();}}// 定义一个同步方法public synchronized void method01(){if (ticket > 0) {System.out.println(Thread.currentThread().getName() + "买了第" + ticket + "张票");ticket--;}}// 在普通方法内用一个同步代码块public void method02(){synchronized (this){System.out.println(this+"————————————————————");if (ticket>0){System.out.println(Thread.currentThread().getName() + "买了第" + ticket + "张票");ticket--;}}}}

       只new了一次对象

2.静态同步方法

① 格式

        修饰符 static synchronized 返回值类型 方法名(参数){

                方法体
                return 结果

        }

② 默认锁

        class对象

package S74ThreadSafeSolve3;import java.util.Scanner;public class MyTicket implements Runnable{// 定义100章票static int ticket = 100;Scanner sc = new Scanner(System.in);@Overridepublic void run(){while(true){try{Thread.sleep(100L);} catch (InterruptedException e) {throw new RuntimeException(e);}// 调用同步方法method02();}}// 在普通方法内用一个同步代码块public static void method02(){synchronized (MyTicket.class){if (ticket>0){System.out.println(Thread.currentThread().getName() + "买了第" + ticket + "张票");ticket--;}}}}
package S74ThreadSafeSolve3;public class Demo213Test {public static void main(String[] args) {// new一次,分别传递到三个线程对象中去MyTicket myTicket = new MyTicket();System.out.println(myTicket);Thread th1= new Thread(myTicket, "赵四");Thread th2= new Thread(myTicket, "刘能");Thread th3= new Thread(myTicket, "广坤");th1.start();th2.start();th3.start();}
}

StringBuider是线程不安全的,StringBuffer加了死锁是线程安全,线程同步的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/14545.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

纹理映射技术在AI去衣中的艺术与科技融合

引言: 在数字图像处理的世界里,AI去衣技术正逐步揭开其神秘的面纱。这门技术结合了深度学习的智能算法与图形学的先进手段,以实现对图像中衣物的智能识别与处理。在这一过程中,纹理映射技术发挥着至关重要的作用。本篇博客将深入探…

变量命名的艺术:从蛇形到驼峰

新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、蛇形命名法的魅力 二、类名和模块名的特殊规则 三、驼峰命名法的魅力与挑战 四、保持…

【kubernetes】探索k8s集群中kubectl的陈述式资源管理

目录 一、k8s集群资源管理方式分类 1.1陈述式资源管理方式:增删查比较方便,但是改非常不方便 1.2声明式资源管理方式:yaml文件管理 二、陈述式资源管理方法 2.1查看版本信息 2.2查看资源对象简写 2.3配置kubectl自动补全 2.4node节点…

初始Java篇(JavaSE基础语法)—— 内部类

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏:JavaSE 目录 内部类的概念 内部类的种类 使用举例: 1. 静态内部类: 2. 实例内部类 3. 局部内部类 4. 匿名内部…

1分钟带你搞定Pandas DataFrame运算

1. DataFrame之间的运算 在运算中自动对齐不同索引的数据 如果索引不对应,则补NaN DataFrame没有广播机制 导包 # 导包import numpy as npimport pandas as pd 创建 DataFrame df1 不同人员的各科目成绩,月考一 # 创建DataFrame二维数组df1 pd.Da…

想要修改Excel表格内容,怎么移除编辑权限?

在使用Excel进行数据处理和管理时,我们经常会遇到需要保护工作表以防止误操作的情况。有时可能碰到“被保护单元格不支持此功能”的提示,本文将详细介绍这个问题的解决方案,帮助你取消单元格保护,使用所需的功能。 一、取消单元格…

leetcode刷题记录:前缀和

https://labuladong.online/algo/problem-set/perfix-sum/#%E8%A7%A3%E6%B3%95%E4%BB%A3%E7%A0%81-3 适用范围:快速、频繁地计算一个索引区间内的元素之和 303 区域和检索:数组不可变 https://leetcode.cn/problems/range-sum-query-immutable/ class …

【Unitydemo制作】音游制作—排行榜逻辑Json存储

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:就业…

GQL 来了!ISO/IEC 正式发布 GQL 数据库国际标准!

历时四年筹备,超过20个国家的标准和技术专家参与制定,ISO/IEC GQL (图查询语言)标准于2024年4月12日正式发布! 作为国际标准化组织(ISO)继 1987年 发布SQL后,唯一发布的数据库查询语…

瑞米派Ubuntu系统移植指南-米尔RemiPi

1.概述 Linux系统平台上有许多开源的系统构建框架,这些框架方便了开发者进行嵌入式系统的构建和定制化开发,目前比较常见的有Buildroot, Yocto, OpenEmbedded等等。 同时更多的传统的桌面系统也加入到嵌入式环境体系中,如Ubuntu&#xff0c…

Marin说PCB之POC电路layout设计仿真案例---03

今天天中午午休的时候,我刚要打开手机的准备刷抖音看无忧传媒的学生们的“学习资料”的时候,看到CSDN -APP上有提醒,一看原来是一位道友发的一个问题: 本来小编最近由于刚刚从国外回来,手上的项目都已经结束了&#xf…

如何制作正方形,给 placeholder 换颜色,多行省略号,纯css小三角,清除浮动,清除 margin,隐藏滚动条,隐藏 number 小图标

https://www.npmjs.com/package/sass-runtime-tool yarn add sass-runtime-tool -D # or npm i -D sass-runtime-tool use "sass-runtime-tool/all.scss" as *;// 改变 placeholder 的颜色和大小 .input {include placeholder(red) {font-size: 12px;} } /* 或者 *…

一个模板元函数来检查一个类是否有一个特定的成员

通过创建一个模板元函数来检查一个类是否有一个特定的成员。以下是一个例子&#xff1a; #include <type_traits>template<typename T, typename void> struct has_type_member : std::false_type {};template<typename T> struct has_type_member<T, s…

Matlab:音频处理

用Matlab绘制一段音频信号在时域上的波形图&#xff0c;然后用低通滤波器滤掉噪音并再次绘制 1、导入音频文件 filename X:\1.mp3; % 替换为你的音频文件路径 [x, Fs] audioread(filename); 2、获取音频信号长度 len length(x); 3、计算时间轴 t (0:len-1) / Fs; 4、…

小程序properties默认值定义及父子组件的传值

因经常写vue&#xff0c;很久没写小程序&#xff0c;容易串频道&#xff0c;现记录一下小程序的组件用法、监听传入值及父子传值方式 首先小程序中传值是没有&#xff1a;(冒号)的&#xff0c;其次properties中定义默认值不需要写default 1.自定义组件中&#xff0c;首先json…

OSPF原理(1)

一、OSPF介绍 OSPF&#xff08;Open Shortest Path First&#xff0c;开放最短路径优先&#xff09;协议作为一种基于链路状态的路由协议&#xff0c;它为网络中的路由器提供了一种高效、可靠的方式来共享路由信息&#xff0c;并计算出最短路径。 特点&#xff1a; 收敛速度快…

踩坑——纪实

开发踩坑纪实 1 npm安装1.1 查看当前的npm镜像设置1.2 清空缓存1.3 修改镜像1.4 查看修改结果1.5 重新安装vue 2 VScode——NPM脚本窗口找不到3 springboot项目中updateById()失效4 前端跨域4.1 后端加个配置类4.2 CrossOrigin注解 5 路由出口6 springdoc openapi3 swagger3文件…

C语言函数递归

文章目录 一、递归1.递归的概念2.递归的思想3.递归的限制条件 二、递归的一些典型例子1.求一个数的阶乘2.顺序打印一个整数的每一位3.汉诺塔4.青蛙跳台阶5斐波那契数列递归和迭代的对比 一、递归 1.递归的概念 递归是学习C语言函数绕不开的一个话题&#xff0c;那什么是递归呢…

【算法刷题day56】 Leetcode:647. 回文子串、516. 最长回文子序列

文章目录 Leetcode 647. 回文子串解题思路代码总结 Leetcode 516. 最长回文子序列解题思路代码总结 草稿图网站 java的Deque Leetcode 647. 回文子串 题目&#xff1a;647. 回文子串 解析&#xff1a;代码随想录解析 解题思路 斜上三角&#xff0c;从左下往上遍历&#xff0c…

【代码随想录】动态规划之完全背包问题与打家劫舍问题

前言 更详细的在大佬的代码随想录 (programmercarl.com) 本系列仅是简洁版笔记&#xff0c;为了之后方便观看 完全背包 for(int i 0; i < weight.size(); i) { // 遍历物品for(int j weight[i]; j < bagWeight; j) { // 遍历背包容量dp[j] max(dp[j], dp[j - weigh…