`

线程间的竞争关系与线程互斥

 
阅读更多
线程间的竞争关系与线程互斥

1.线程间的竞争关系
        同一个进程中的多个线程由系统调度而并发执行时,彼此之间没有直接联系,并不知道其他线程的存在,一般情况下,也不受其他线程执行的影响。但是,如果两个线程要访问同一资源,则线程间存在资源竞争关系,这是线程间的间接制约关系。一个线程通过操作系统分配得到该资源,另一个将不得不等待,这时,一个线程的执行可能影响到同其竞争资源的其他线程。
       在极端的情况下,被阻塞线程永远得不到访问权,从而不能成功地终止。所以,资源竞争出现了两个问题 :
        一是死锁(deadlock)问题,一组线程如果都获得了部分资源,还想要得到其他线程所占用的资源,最终所有的线程将陷入死锁;
        二是饥饿(starvation)问题,一个线程由于其他线程总是优于它而被无限期拖延。
例如:一个路口的交通信号灯控制,如果4个方向都是绿灯,汽车抢行造成路堵,这是死锁。
      如果4个方向都是红灯,谁也不能走,这是饥饿。
操作系统负责资源分配,操作系统必须协调好线程对资源的争用。操作系统需要保证诸线程能互斥地访问临界资源,既要解决饥饿问题,也要解决死锁问题
2.线程互斥和临界区管理
         线程互斥(mutual exclusion)是解决线程间竞争关系的手段。线程互斥是指若干个线程要使用同一共享资源时,任何时刻最多允许一个线程去使用,其他要使用该资源的线程必须等待,直到占有资源的线程释放该资源。
         把共享变量代表的资源称为临界资源(critical resource),并发线程中与共享变量有关的程序段称为临界区(critical section)。由于与同一变量有关的临界区分散在各有关线程的程序段中,而各线程的运行速度不可预知,操作系统对共享一个变量的若干线程进入各自临界区有以下3个调度原则:
      (1)一次至多一个线程能够在它的临界区内。
      (2)不能让一个线程无限期地留在它的临界区内。
      (3)不能强迫一个线程无限地等待进入它的临界区。特别地,进入临界区的任一线程不能妨碍正等待进入的其他线程的进展。
      把临界区的调度原则总结成四句话:无空等待、有空让进、择一而入、算法可行。算法可行,是指不能因为所选的调度策略造成线程饥饿甚至死锁。这样能保证一个线程在临界区执行时,不让另一个线程进入相关的临界区,即各线程对共享变量的访问是互斥的,就不会造成与时间有关的错误。
       操作系统提供“互斥锁”机制实现并发线程互斥地进入临界区,对共享资源进行操作。至于操作系统采用什么样的锁(信号灯、只读锁等)以及如何实现加锁和解锁等问题,Java程序员并不需要关心,这些细节都由操作系统和Java虚拟机来处理,程序员只需要在程序中声明哪个程序段是临界区即可,采用Java抽象的锁模型,就能够使程序在所有平台上可靠地、可预见地运行。

Java的线程互斥实现
   Java提供关键字synchronized用于声明一段程序为临界区,使线程对临界资源采用互斥使用方式。synchronized有两种用法:声明一条语句、声明一个方法。
(1)同步语句
   使用synchronized声明一条语句为临界区,该语句称为同步语句,语法格式如下:
         synchronized(对象)
                语句
    其中,<对象>是多个线程共同操作的公共变量,即需要被锁定的临界资源,它将被互斥地使用;<语句>是临界区,它描述线程对临界资源的操作,如果是多条语句需要用{}括起来成为一条复合语句。
      一个同步语句允许一个对象锁保护一个单独的语句(也包括一个复合语句),在执行这个语句前,必须获得这个对象锁。
     同步语句执行过程如下:
    当第1个线程进入临界区执行(语句)时,它获得临界资源即指定(对象)的使用权,并将对象加锁,然后执行语句对对象进行操作。
      在此过程中,如果有第2个线程也希望对同一个对象执行这条语句,由于作为临界资源的对象已被锁定,则第2个线程必须等候。
      当第1个线程执行完临界区语句,它将释放对象锁。
      之后,第2个线程才能获得对象的使用权并运行。
      这样,对于同一个对象,在任何时刻都只能有一个线程执行临界区语句,对该对象进行操作,其他竞争使用该对象的线程必须等待,直到对象锁被释放。这就实现了多个并发执行的交互线程间对同一个临界资源的互斥使用。

(2)同步方法
              使用synchronized声明一个方法,该方法称为同步方法,语法格式如下:
                synchronized   方法声明
    这样,同步方法的方法体成为临界区,互斥使用(锁定)的是调用该方法的对象。该声明与以下声明效果相同:
      方法声明
      
synchronized(this)
       {
            方法体
        }

  
同步语句与同步方法的行为基本相似,只是同步语句的作用范围小,它只是锁住一条语句(或复合语句)而不是完整的方法,并指定所要获得锁的对象而不调用方法的对象。这样就增加了灵活性,并且缩小了对象锁的作用域。

package com.jbx.thread;

public class SaveLock extends Thread{    //带互斥锁的存款线程类

    private Account account;  //账户  
    private double value;     //存款金额  
      
    public SaveLock(Account al ,double value){  
        this.account = al;  
        this.value = value;  
    }  

	public void run() {
		 synchronized (this.account) { // 声明临界区 

			double howmatch = this.account.getBalance();// 查看账户余额
			
			try {
				sleep(1); // 花费实际,线程执行被打断
			} catch (InterruptedException e) {
			}
			this.account.put(this.value);
			System.out.println(this.account.getName() + "账户:现有" + howmatch
					+ ",存入" + this.value + ",余额" + this.account.getBalance());
		 } 
	}
	 public static void main(String[] args) {  
	        Account wang = new Account("wang");  
	        (new SaveLock(wang,1000)).start();     
	        (new SaveLock(wang,200)).start();     
	        (new FetchLock(wang,300)).start();    
	    }  
}  
class FetchLock extends Thread{  
    private Account account;  //   
    private double value;     //   
      
    public FetchLock(Account al ,double value){  
        this.account = al;  
        this.value = value;  
    }  
      
    public void run(){ 
    	 synchronized(this.account){  //声明临界区,锁定指定账户对象 
	        double howmatch = this.account.getBalance();//查看账户余额  
	       
	        try {  
	            sleep(1);                              //花费实际,线程执行被打断  
	        } catch (InterruptedException e) {}  
	        System.out.println(this.account.getName()+"账户:现有"+howmatch+",取走"+this.account.get(this.value)+",余额"+this.account.getBalance());  
	    	 }  
    }
   
}  

 class Account {        //账户类  
    private String name;     //储户姓名  
    private double balance;  //账户余额  
      
    public Account(String name) {  
        this.name = name;  
        this.balance = 0;  
    }  
    public String getName() {     //返回账户名  
        return name;  
    }  
  
    public double getBalance() {   //查看账户余额  
        return balance;  
    }  
      
    public void put(double value) {   //存款操作,参数为存入金额  
        if(value>0)  
        this.balance += value;        //存款操作使余额值增加//存款操作,参数为取款金额,返回实际取到金额  
    }  
      
    public double get(double value){  //取款操作,参数为取款金额,返回实际取到金额  
        if(value>0){  
            if(value<=this.balance)  
                this.balance -= value;  //取款操作使余额值减少  
            else{  
                value= this.balance;    //取走全部余额  
                this.balance = 0;   
            }  
            return value;              //返回实际取款额  
        }  
        return 0;  
    }  
}  

运行结果:
wang账户:现有0.0,存入1000.0,余额1000.0
wang账户:现有1000.0,取走300.0,余额700.0
wang账户:现有700.0,存入200.0,余额900.0



本例将存/取款线程体设置位针对同一个账户对象互斥使用的临界区,也可以将put()和get()方法声明为临界区。每个线程在运行前,都要先查看账户对象的锁定状态。如果对象被锁定,则等待;如果对象未锁定,则获得使用权,运行临界区中的代码,即使线程执行被打断,也不释放对象锁,只有当线程执行完才释放对象锁。这样不仅使得任何时刻只有一个线程对同一个账户进行操作,而且保证每个线程执行的多个操作是连续的,期间不会被其他线程干扰,最终查看金额、存入金额和剩余金额的结果相符,保证了数据的完整性和一致性。
分享到:
评论

相关推荐

    实时监控体系:基于Prometheus的API性能指标可视化方案.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    5个提升DeepSeekAPI生成质量的调参技巧,开发者必看!.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    ACM动态规划模板-区间修改线段树问题模板

    ACM动态规划模板-区间修改线段树问题模板

    深度解析C语言调试技巧:VSCode+GDB实战排错指南.pdf

    # 踏入C语言的奇妙编程世界 在编程的广阔宇宙中,C语言宛如一颗璀璨恒星,以其独特魅力与强大功能,始终占据着不可替代的地位。无论你是编程小白,还是有一定基础想进一步提升的开发者,C语言都值得深入探索。 C语言的高效性与可移植性令人瞩目。它能直接操控硬件,执行速度快,是系统软件、嵌入式开发的首选。同时,代码可在不同操作系统和硬件平台间轻松移植,极大节省开发成本。 学习C语言,能让你深入理解计算机底层原理,培养逻辑思维和问题解决能力。掌握C语言后,再学习其他编程语言也会事半功倍。 现在,让我们一起开启C语言学习之旅。这里有丰富教程、实用案例、详细代码解析,助你逐步掌握C语言核心知识和编程技巧。别再犹豫,加入我们,在C语言的海洋中尽情遨游,挖掘无限可能,为未来的编程之路打下坚实基础!

    10个高效调用DeepSeekAPI的技巧:从请求优化到缓存策略.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    基于Python语言的PersonRelationKnowledgeGraph设计源码

    本项目为Python语言开发的PersonRelationKnowledgeGraph设计源码,总计包含49个文件,涵盖19个.pyc字节码文件、12个.py源代码文件、8个.txt文本文件、3个.xml配置文件、3个.png图片文件、2个.md标记文件、1个.iml项目配置文件、1个.cfg配置文件。该源码库旨在构建一个用于表示和查询人物关系的知识图谱系统。

    成本优化指南:通过Token计算模型将API费用降低57%的秘诀.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    大华智能物联平台,的对接其他接口的API,可以获得视频拉流的flv/hls/rstp 的拉流地址,demo项目为springBoot项目,可以通过摄像头的视频通道,获取到实时拉流的uRl

    rtsp实时预览接口URL:/evo-apigw/admin/API/MTS/Video/StartVideo HLS、FLV、RTMP实时预览接口方式 :接口URL/evo-apigw/admin/API/video/stream/realtime 参数名 必选 类型 说明 data true string Json串 +channelId true string 视频通道编码 +streamType true string 码流类型:1=主码流, 2=辅码流,3=辅码流2 +type true string 协议类型:hls,hlss,flv,flvs,ws_flv,wss_flv,rtmp hls:http协议,m3u8格式,端口7086; hlss:https协议,m3u8格式,端口是7096; flv:http协议,flv格式,端口7886; flvs:https协议,flv格式,端口是7896; ws_flv:ws协议,flv格式,端口是7886; wss_flv:wss协议,flv格式,端口是7896; rtmp:rtmp协议,端口是1975;

    Simulink永磁风机飞轮储能系统二次调频技术研究:频率特性分析与参数优化,Simulink永磁风机飞轮储能二次调频技术:系统频率特性详解及参数优化研究参考详实文献及两区域系统应用,simulink

    Simulink永磁风机飞轮储能系统二次调频技术研究:频率特性分析与参数优化,Simulink永磁风机飞轮储能二次调频技术:系统频率特性详解及参数优化研究参考详实文献及两区域系统应用,simulink永磁风机飞轮储能二次调频,系统频率特性如下,可改变调频参数改善频率。 参考文献详细,两区域系统二次调频。 ,核心关键词: 1. Simulink 2. 永磁风机 3. 飞轮储能 4. 二次调频 5. 系统频率特性 6. 调频参数 7. 改善频率 8. 参考文献 9. 两区域系统 以上关键词用分号(;)分隔,结果为:Simulink;永磁风机;飞轮储能;二次调频;系统频率特性;调频参数;改善频率;参考文献;两区域系统。,基于Simulink的永磁风机与飞轮储能系统二次调频研究:频率特性及调频参数优化

    MATLAB驱动的ASR防滑转模型:PID与对照控制算法对比,冰雪路面条件下滑移率与车速轮速对照展示,MATLAB驱动的ASR防滑转模型:PID与对照控制算法对比,冰雪路面条件下滑移率与车速轮速对照图

    MATLAB驱动的ASR防滑转模型:PID与对照控制算法对比,冰雪路面条件下滑移率与车速轮速对照展示,MATLAB驱动的ASR防滑转模型:PID与对照控制算法对比,冰雪路面条件下滑移率与车速轮速对照图展示,MATLAB驱动防滑转模型ASR模型 ASR模型驱动防滑转模型 ?牵引力控制系统模型 选择PID控制算法以及对照控制算法,共两种控制算法,可进行选择。 选择冰路面以及雪路面,共两种路面条件,可进行选择。 控制目标为滑移率0.2,出图显示车速以及轮速对照,出图显示车辆轮胎滑移率。 模型简单,仅供参考。 ,MATLAB; ASR模型; 防滑转模型; 牵引力控制系统模型; PID控制算法; 对照控制算法; 冰路面; 雪路面; 控制目标; 滑移率; 车速; 轮速。,MATLAB驱动的ASR模型:PID与对照算法在冰雪路面的滑移率控制研究

    芯片失效分析方法介绍 -深入解析芯片故障原因及预防措施.pptx

    芯片失效分析方法介绍 -深入解析芯片故障原因及预防措施.pptx

    4131_127989170.html

    4131_127989170.html

    PostgreSQL自动化部署与优化脚本:智能化安装、安全加固与监控集成

    内容概要:本文提供了一个全面的PostgreSQL自动化部署解决方案,涵盖智能环境适应、多平台支持、内存与性能优化以及安全性加强等重要方面。首先介绍了脚本的功能及其调用方法,随后详细阐述了操作系统和依赖软件包的准备过程、配置项的自动生成机制,还包括对实例的安全性和监控功能的强化措施。部署指南给出了具体的命令操作指导,便于新手理解和执行。最后强调了该工具对于不同硬件条件和服务需求的有效应对能力,特别是针对云计算环境下应用的支持特点。 适合人群:对PostgreSQL集群运维有一定基础并渴望提高效率和安全性的数据库管理员及工程师。 使用场景及目标:本脚本能够帮助企业在大规模部署时减少人工介入时间,确保系统的稳定性与高性能,适用于各类需要稳定可靠的数据库解决方案的企业或机构,特别是在大数据量和高并发事务处理场合。 其他说明:文中还提及了一些高级功能如自动备份、流复制等设置步骤,使得该方案不仅可以快速上线而且能满足后续维护和发展阶段的要求。同时提到的技术性能数据也为用户评估其能否满足业务需求提供了直观参考。

    房地产开发合同[示范文本].doc

    房地产开发合同[示范文本].doc

    成本优化实战:DeepSeekAPI的Tokens计算与计费策略拆解.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    安全必读:DeepSeek接口调用中的数据加密与合规实践.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    工程技术承包合同[示范文本].doc

    工程技术承包合同[示范文本].doc

    蓝桥杯开发赛作品源码【基于C语言】

    蓝桥杯开发赛【作品源码】

    深度解析DeepSeek语义分析API:实现情感分析与意图识别的进阶技巧.pdf

    在日常的工作和学习中,你是否常常为处理复杂的数据、生成高质量的文本或者进行精准的图像识别而烦恼?DeepSeek 或许就是你一直在寻找的解决方案!它以其高效、智能的特点,在各个行业都展现出了巨大的应用价值。然而,想要充分发挥 DeepSeek 的优势,掌握从入门到精通的知识和技能至关重要。本文将从实际应用的角度出发,为你详细介绍 DeepSeek 的基本原理、操作方法以及高级技巧。通过系统的学习,你将能够轻松地运用 DeepSeek 解决实际问题,提升工作效率和质量,让自己在职场和学术领域脱颖而出。现在,就让我们一起开启这场实用又高效的学习之旅吧!

    CVPR2023复现技术:多数据集验证下的YOLOX、YOLOv5及YOLOV7检测涨点助力器,CVPR2023复现实验助力检测涨点,验证了YOLOX、YOLOv5及YOLOV7在多个数据集上的有效性

    CVPR2023复现技术:多数据集验证下的YOLOX、YOLOv5及YOLOV7检测涨点助力器,CVPR2023复现实验助力检测涨点,验证了YOLOX、YOLOv5及YOLOV7在多个数据集上的有效性,cvpr2023复现,助力检测涨点,YOLOX YOLOv5 YOLOV7均有效,再多个数据集验证有效 ,cvpr2023复现; 助力检测涨点; YOLOX有效; YOLOv5有效; YOLOV7有效; 多数据集验证有效,CVPR2023复现成功:多模型检测涨点验证有效

Global site tag (gtag.js) - Google Analytics