并发编程---线程安全

一.三大特性

1.原子性(线程任务不可再分)

一个操作或者多个操作要么全部执行,要么全部不执行。这确保了数据的一致性,避免了部分执行导致的数据错误。

原子类(Atomic)

//  static int x = 1;static AtomicInteger x = new AtomicInteger(1);//原子类创建public static void main(String[] args) {Thread t1 = new Thread(new Runnable() {@Overridepublic void run() {try {for (int i = 0;i < 100;i++){System.out.println(x.addAndGet(1));Thread.sleep(100);}} catch (InterruptedException e) {throw new RuntimeException(e);}}});Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {try {for (int i = 0;i < 100;i++){System.out.println(x.addAndGet(1));Thread.sleep(100);}} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.start();t2.start();}

2.可见性(线程之间的操作是互相不可见的)

volatile

当多个线程访问同一变量时,其中一个线程修改了这个变量,其他线程必须立刻知道这个变量被修改的值。这保证了数据的实时更新和一致性。

    static boolean flag = false;public static void main(String[] args) {//线程A如果flag为true,就运行打印语句A:trueThread t1 = new Thread(() -> {while (true) {if (flag){System.out.println("A:" + flag);}}});//100ms之后将flag变为trueThread t2 = new Thread(() -> {try {Thread.sleep(100);flag = true;System.out.println("B:" + flag);} catch (InterruptedException e) {throw new RuntimeException(e);}});t1.start();t2.start();}

3.有序性(程序运行顺序不能改变)

在一个线程内观察,所有操作都是有序的;但从一个线程观察另一个线程,所有操作都是无序的。这确保了线程之间的操作不会相互干扰,保持了操作的独立性。

二.线程安全性解决方案-锁

1.锁的使用过程

  1.每一个对象只有一把锁

  2.每个线程抢锁,谁先抢到这个线程就是锁的持有者。

  3.持有锁的线程访问有synchronized 标记的方法/代码块

  4.离开synchronized,线程释放锁

2.模拟场景

火车票抢购

~有100张车票

~多个站点在卖票A,B,C

~100张票共享给A,B,C

~每卖出一张票,票--;

~当票==0,卖票终止。

3.Ticket

public class Ticket {private Integer num;private String name;public Ticket(int num) {this.num = num;}/*** 取出剩余的票数量* @return*/public int getNum() {return num;}/*** 卖票* @param name*/
//    public synchronized void sold(String name){
//        System.out.println("站点" + name + "售出一张票,还剩:" + (--num));
//    }public void sold(String name){//--num   num-1 --> numsynchronized (num){System.out.println("站点" + name + "售出一张票,还剩:" + (--num));}}
}
public class StationThread extends Thread{private Ticket ticket;private String name;public StationThread(Ticket ticket,String name){this.ticket = ticket;this.name = name;}public void run() {while (ticket.getNum() > 0){try {sleep(100);ticket.sold(name);} catch (InterruptedException e) {throw new RuntimeException(e);}}}}
public class TicketTest {public static void main(String[] args) {Ticket ticket = new Ticket(100);Thread a = new StationThread(ticket,"A");Thread b = new StationThread(ticket,"B");Thread c = new StationThread(ticket,"C");a.start();b.start();c.start();}
}

4.同步锁

  线程安全的同步锁是通过使用同步机制来确保多个线程在访问共享资源时的数据一致性和防止竞态条件,从而避免数据损坏或程序行为不可预测的问题。‌

  线程安全的同步锁的实现主要依赖于同步代码块和同步方法,以及更高级的同步工具如读写锁、信号量、条件变量和事件。这些机制和工具的共同目标是通过协调多个线程的执行,确保它们不会同时操作相同的数据或资源,从而保持数据的一致性和防止竞态条件。

public class Resource {private String name;public Resource(String name) {this.name = name;}@Overridepublic String toString() {return "Resource [name=" + name + "]";}
}
public class DeadLockDemo extends Thread {private Resource a;private Resource b;public DeadLockDemo(Resource a, Resource b) {this.a = a;this.b = b;}@Overridepublic void run() {System.out.println("准备锁定: " + a);synchronized (a) {try {sleep(200);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("资源:" + a + "锁定成功....");System.out.println("准备锁定: " + b);synchronized (b) {System.out.println("资源:" + b + "锁定成功....");}System.out.println("释放资源:" + b + "成功...");}System.out.println("释放资源:" + a + "成功...");}
}
Resource r1 = new Resource("A");
Resource r2 = new Resource("B");
Resource r3 = new Resource("C");Thread t1 = new DeadLockDemo(r1, r2);
Thread t2 = new DeadLockDemo(r2, r3);
Thread t3 = new DeadLockDemo(r3, r1);t1.start();
t2.start();
t3.start();

5.死锁

  死锁‌是一种特殊的现象,发生在多个线程或进程因争夺资源而相互等待,导致它们都无法继续执行的情况。死锁的四个必要条件包括互斥条件、请求与保持条件、不剥夺条件和环路等待条件。这些条件共同作用,使得资源请求和释放的顺序不当,从而导致系统资源无法有效利用,进而产生死锁‌。

public class Resource {private String name;public Resource(String name) {this.name = name;}public String getName() {return name;}@Overridepublic String toString() {return "Resource{" +"name='" + name + '\'' +'}';}
}
public class DeadLockThread extends Thread{private Resource x;private Resource y;public DeadLockThread(Resource x,Resource y){this.x = x;this.y = y;}@Overridepublic void run() {synchronized (x){System.out.println(x.getName() + "锁定" + x.getName() + "成功...");try {sleep(200);System.out.println(x.getName() + "准备--->锁定" + y.getName() + ">>>>>");synchronized (y){System.out.println(x.getName() + "锁定" + y.getName() + "成功...");}System.out.println("释放" + y.getName() + "成功...");} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("释放" + x.getName() + "成功...");}
}
public class Main {public static void main(String[] args) {Resource a = new Resource("A");Resource b = new Resource("B");Resource c = new Resource("C");Thread i = new DeadLockThread(a,b);Thread j = new DeadLockThread(b,c);Thread k = new DeadLockThread(c,a);i.start();j.start();k.start();}
}

运行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

yub‘s Algorithmic Adventures_Day1

Day 1 二分查找 如理解有误欢迎指正交流~ link&#xff1a;704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; 思路分析 题目给出数组升序 &#xff0c;想到二分查找&#xff08;好吧其实题目也给出来了w&#xff09; 找到mid&#xff0c;根据逻辑大小缩小范围比较. …

大模型价格战,打到了负毛利,卷or不卷?

国产大模型淘汰赛在加速。这轮淘汰赛会持续一两年&#xff0c;只有少数真正具备实力的基础模型企业能继续活下去 中国市场的大模型价格战已经打了近半年。这轮价格战已经打到了负毛利&#xff0c;而且暂时没有停止迹象。头部云厂商仍在酝酿新一轮降价。这轮降价会在今年9月下旬…

270万骑手,如何“送”出一个IPO?

2018年美团上市&#xff0c;敲钟之后的王兴在致辞中&#xff0c;特别感谢了「重新发明手机」的乔布斯&#xff1a; “如果没有移动互联网&#xff0c;没有智能手机&#xff0c;我们今天所做的一切都是不可能的事情。” 彼时的中国市场&#xff0c;庞大的人口红利和快速发展的…

mov转gif怎么快速转换?5个软件帮助你轻松进行文件格式转换

mov转gif怎么快速转换&#xff1f;5个软件帮助你轻松进行文件格式转换 将 MOV 格式的视频转换为 GIF 动图是一项非常实用的任务&#xff0c;无论是为了在社交媒体上分享&#xff0c;还是用于创建简短的演示。以下是五款能够快速、高效地将 MOV 转换为 GIF 的软件和工具&#x…

Java浅谈Java String内幕

​ 博客主页: 南来_北往 系列专栏&#xff1a;Spring Boot实战 前言 Java中的String类是一个不可变的、用于表示字符串的类。在Java中&#xff0c;字符串是通过字符数组来实现的&#xff0c;而String类则是对这个字符数组进行封装&#xff0c;并提供了一系列操作字符串的…

c++ 类中特殊成员函数

作业&#xff1a; 仿照string类&#xff0c;自己手动实现 My_string&#xff0c;分文件编译 fun.h代码 #ifndef FUN_H #define FUN_H#include <iostream>using namespace std;class My_string { private:char *ptr; // 指向字符数组的指针int size; // 字符串的最大…

计算机毕业设计推荐-基于python的游戏资讯分享平台

精彩专栏推荐订阅&#xff1a;在下方主页&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主页&#xff1a;计算机毕设木哥&#x1f525; &#x1f496; 文章目录 一、基于python的…

2024重生之回溯数据结构与算法系列学习(4)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】

目录 数据结构王道第2.3章节之线性表精题汇总一 &#xff08;10&#xff09;题目:​编辑 解题思路&#xff1a; 实现代码&#xff1a; &#xff08;11&#xff09;题目&#xff1a; 解题思路&#xff1a; &#xff08;12&#xff09;题目&#xff1a; 解题思路&#xff1a; 实…

Set 和 Map 的模拟实现

1、引言 在数据结构与算法的学习与实践中&#xff0c;关联容器&#xff08;associative containers&#xff09;是不可忽视的重要工具。作为高效管理数据的一类容器&#xff0c;C 标准库中的 set 和 map 在现代软件开发中扮演着关键角色。这两个容器通过平衡二叉搜索树&#x…

软件测试常见面试题

目录 1、什么是测试用例? 2、什么是BUG?(BUG的生命周期) 3、软件开发五大模型 4、软件测试的生命周期 5、测试模型(V模型、W模型) 6、软件开发的生命周期 7、如何描述一个BUG? 8、BUG的级别(线上出现崩溃级别的BUG怎么办) 9、 BUG的生命周期 10、发现一个BUG…

Qt系统相关——QFile和QFileInfo

文章目录 文件操作QFile使用示例QFileInfo 文件操作 C语言&#xff1a; fopen打开文件fread、fwrite读写文件fclose关闭文件 C&#xff1a; fstream打开文件<<、>>流式操作符读写 Linux&#xff1a; open打开文件read、write读写文件close关闭文件 Qt自己也…

把任务管理器里面的vmware usb arbitrition停了,虚拟机一直识别不到手机设备了

在设备管理器--服务 里面找到VMware usb arbitrition服务&#xff0c;点击“启用”就好了。 参考大佬的文章&#xff1a; 吐血经验&#xff01;&#xff01;&#xff01;解决虚拟机连不上USB&#xff01;最全&#xff01;_为什么vmware虚拟机不能连接上usb设备-CSDN博客

地平线静态目标检测 MapTR 参考算法-V1.0

简介 高清地图是自动驾驶系统的重要组件&#xff0c;提供精确的驾驶环境信息和道路语义信息。传统离线地图构建方法成本高&#xff0c;维护复杂&#xff0c;使得依赖车载传感器的实时感知建图成为新趋势。早期实时建图方法存在局限性&#xff0c;如处理复杂地图元素的能力不足…

品牌互鉴,融通中外|AORO遨游创始人受邀参加2024北京国际品牌周

2024年9月21日&#xff0c;第三届北京国际品牌周在北京金融街英蓝国际金融中心举办&#xff0c;本次盛会以“品牌互鉴&#xff0c;融通中外”为主题&#xff0c;由中国国际商会、中国国际公共关系协会、中国文化管理协会、北京国际设计周主办&#xff0c;中国外文局文化传播中心…

LSM-YOLO: A Compact and Effective ROI Detector for Medical Detection

LSM-YOLO: A Compact and Effective ROI Detector for Medical Detection LSM-YOLO: 一种紧凑且有效的医学检测ROI检测器1.介绍2.相关工作2.1医学感兴趣区域&#xff08;ROI&#xff09;检测2.2多尺度特征用于对象检测 3方法3.1LAE(轻量级自适应提取&#xff09;3.2MSFM(多路径…

GESP等级考试C++二级-switch...case的用法

在《GESP等级考试C二级if语句》中提到&#xff0c;可以使用if...else if...else语句来处理多种可能的情况。在C中&#xff0c;使用switch...case语句也可以来处理多种可能。 1 switch...case语句的格式 switch...case语句的格式如图1所示。 图1 switch...case语句的格式 其中…

鸿蒙开发(NEXT/API 12)【基础功能(使用剪贴板进行复制粘贴)】剪贴板服务

场景介绍 [剪贴板]为开发者提供数据的复制粘贴能力。 当需要使用复制粘贴等功能时&#xff0c;例如&#xff1a;复制文字内容到备忘录中粘贴&#xff0c;复制图库照片到文件管理粘贴&#xff0c;就可以通过剪贴板来完成。 约束限制 剪贴板内容大小<128MB。为保证剪贴板数…

【TabBar嵌套Navigation案例-产品推荐页面-UICollectionView-结合xib使用 Objective-C语言】

一、接下来,我们来说这个产品推荐页面 1.首先呢,它是一个CollectionViewController,当我点击这个产品推荐的时候, 这个Cell的时候,我要跳到一个CollectionViewController, 所以呢,我们需要先找到产品推荐,然后给它去添加一个targetVC,然后给它push到一个产品推荐的页面…

AI大模型的前十岗位薪资,谁还说读书没用?零基础入门到精通,收藏这一篇就够了

1. AI系统架构师 薪资范围&#xff1a;100万 - 200万/年 职位要求&#xff1a;需要具备全面的技术背景&#xff0c;精通系统架构设计&#xff0c;能够有效整合AI技术&#xff0c;提升系统性能。要求硕士及以上学历&#xff0c;计算机科学或相关专业背景。 目标院校&#xff1…

使用Conda配置python环境到Pycharm------Window小白版

使用Conda配置python环境到Pycharm 一、Conda安装和环境配置1.1 安装Conda软件1.2 判断是否安装成功1.3 创建Conda虚拟环境 二、 pycharm的安装2.1 Pycharm使用手册2.2 安装pycharm 三、 pycharm导入Conda环境 一、Conda安装和环境配置 anaconda官网 1.1 安装Conda软件 运行…