- 浏览: 191497 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
grzrt:
zkf55915 写道哥们怎么用啊
好久不用了,就是看帮助资 ...
淘宝MetaQ开源消息队列安装 -
zkf55915:
哥们怎么用啊
淘宝MetaQ开源消息队列安装 -
grzrt:
jinnianshilongnian 写道整这个了?
没有 看 ...
linux内核中链表的实现 -
jinnianshilongnian:
整这个了?
linux内核中链表的实现
Mutex是互斥体,广泛地应用在多线程编程中。本文以广为流程的Doug Lea的concurrent工具包的Mutex实现为例,进行一点探讨。在Doug Lea的concurrent工具包中,Mutex实现了Sync接口,该接口是concurrent工具包中所有锁(lock)、门(gate)和条件变量(condition)的公共接口,Sync的实现类主要有:Mutex、Semaphore及其子类、Latch、CountDown、ReentrantLock等。这也体现了面向抽象编程的思想,使我们可以在不改变代码或者改变少量代码的情况下,选择使用Sync的不同实现。下面是Sync接口的定义:
public interface Sync{ public void acquire() throws InterruptedException; //获取许可 public boolean attempt(long msecs) throws InterruptedException; //尝试获取许可 public void release(); //释放许可}
通过使用Sync可以替代Java synchronized关键字,并提供更加灵活的同步控制。当然,并不是说 concurrent工具包是和Java synchronized独立的技术,其实concurrent工具包也是在synchronized的基础上搭建的,从下面对Mutex源码的解析即可以看到这一点。synchronized关键字仅在方法内或者代码块内有效,而使用Sync却可以跨越方法甚至通过在对象之间传递,跨越对象进行同步。这是Sync及concurrent工具包比直接使用synchronized更加强大的地方。
注意Sync中的acquire()和attempt()都会抛出InterruptedException,所以使用Sync及其子类时,调用这些方法一定要捕获InterruptedException.而release()方法并不会抛出InterruptedException,这是因为在acquire()和attempt()方法中可能会调用wait()等待其它线程释放锁。而release()在实现上进行了简化,直接释放锁,不管是否真的持有。所以,你可以对一个并没有acquire()的线程调用release()这也不会有什么问题。而由于release()不会抛出InterruptedException,所以我们可以在catch或finally子句中调用release()以保证获得的锁能够被正确释放。比如:
class X{ Sync gate; // ... public void m() { try { gate.acquire(); // block until condition holds try { // ... method body } finally { gate.release(); } } catch (InterruptedException ex) { // ... evasive action } }}
Mutex是一个非重入的互斥锁。Mutex广泛地用在需要跨越方法的before/after类型的同步环境中。下面是Doug Lea的concurrent工具包中的Mutex的实现。
public class Mutex implements Sync{ /** The lock status **/ protected boolean inuse_ = false; public void acquire() throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException();//(1) synchronized(this) { try { while (inuse_) wait(); inuse_ = true; } catch (InterruptedException ex) { //(2) notify(); throw ex; } } } public synchronized void release() { inuse_ = false; notify(); } public boolean attempt(long msecs) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); synchronized(this) { if (!inuse_) { inuse_ = true; return true; } else if (msecs <= 0) return false; else { long waitTime = msecs; long start = System.currentTimeMillis(); try { for (;;) { wait(waitTime); if (!inuse_) { inuse_ = true; return true; } else { waitTime = msecs - (System.currentTimeMillis() - start); if (waitTime <= 0) // (3) return false; } } } catch (InterruptedException ex) { notify(); throw ex; } } } }}
为什么要在acquire()和attempt(0方法的开始都要检查当前线程的中断标志呢?这是为了在当前线程已经被打断时,可以立即返回,而不会仍然在锁标志上等待。调用一个线程的interrupt()方法根据当前线程所处的状态,可能产生两种不同的结果:当线程在运行过程中被打断,则设置当前线程的中断标志为true;如果当前线程阻塞于wait()、sleep()、join(),则当前线程的中断标志被清空,同时抛出InterruptedException.所以在上面代码的位置(2)也捕获了InterruptedException,然后再次抛出InterruptedException.
release()方法简单地重置inuse_标志,并通知其它线程。
attempt()方法是利用Java的Object.wait(long)进行计时的,由于Object.wait(long)不是一个精确的时钟,所以attempt(long)方法也是一个粗略的计时。注意代码中位置(3),在超时时返回。
Mutex是Sync的一个基本实现,除了实现了Sync接口中的方法外,并没有添加新的方法。所以,Mutex的使用和Sync的完全一样。在concurrent包的API中Doug给出了一个精细锁定的List的实现示例,我们这儿也给出,作为对Mutex和Sync使用的一个例子:
class Node{ Object item; Node next; Mutex lock = new Mutex(); // 每一个节点都持有一个锁 Node(Object x, Node n) { item = x; next = n; }}class List{ protected Node head; // 指向列表的头 // 使用Java的synchronized保护head域 // (我们当然可以使用Mutex,但是这儿似乎没有这样做的必要 protected synchronized Node
getHead() { return head; } boolean search(Object x) throws InterruptedException { Node p = getHead(); if (p == null) return false; // (这儿可以更加紧凑,但是为了演示的清楚,各种情况都分别进行处理) p.lock.acquire(); // Prime loop by acquiring first lock. // (If the acquire fails due
to // interrupt, the method will throw // InterruptedException now, // so there is no need for any // further cleanup.) for (;;) { if (x.equals(p.item)) { p.lock.release(); // 释放当前节点的锁 return true; } else { Node nextp = p.next; if
(nextp == null) { p.lock.release(); // 释放最后持有的锁 return false; } else { try { nextp.lock.acquire(); // 在释放当前锁之前获取下一个节点的锁 } catch (InterruptedException ex) { p.lock.release(); // 如果获取失败,也释放当前的锁
throw ex; } p.lock.release(); // 释放上个节点的锁,现在已经持有新的锁了 p = nextp; } } } } synchronized void add(Object x) { // 使用synchronized保护head域 head = new Node(x, head); } // ... other similar traversal and update methods ...}
发表评论
-
项目代码质量控制
2014-10-20 17:15 865在以后的开发项目时可以适当使用工具进行程序检查: 1、F ... -
WorkbookFactory 找不到
2013-11-08 10:46 1053在最近的POI版本中,poi-3.9.jar包中找不到Work ... -
记一次JVM GC日志分析
2013-03-08 21:36 1777这几天在准备升级JDK版本到1.6,对目前线上JVM(版 ... -
Eclipse 相同变量的高亮 及颜色
2013-02-18 17:26 1694在Eclipse/MyEclipse中如果不小心把变量的高 ... -
java jstack dump 线程 介绍 解释
2013-02-05 15:52 1235hi,all: 最近抽时间把JVM运行 ... -
[转载]JDMK 基本JMX配置( html adaptor)
2013-01-07 13:37 1793原文地址: JDMK 基本JMX配置( html adap ... -
JAVA中的继承分析
2012-12-27 11:43 5226为什么写这篇博客,之前对继承的理解知识大体理论上,最近 ... -
JVM学习之:虚拟机中的运行时栈帧总结(二)
2012-12-12 19:46 857在 JVM学习之:虚拟机� ... -
JVM学习之:虚拟机中的运行时栈帧总结(一)
2012-12-12 19:45 905每 个人都知道,各种各样的动画视频,都是由一帧一帧图片连 ... -
JAVA字符串占位符
2012-12-06 08:24 3249包 java.text.MessageFormat java ... -
copy项目是容易出现的错误--webAppRootKey错误
2012-12-05 21:18 747Tomcat 发布多个项目时抛的webAppRootKey错误 ... -
web.xml配置总结
2012-12-05 20:50 719一、关于webAppRootKey的定义 默 ... -
spring组件扫描<context:component-scan/>使用详解
2012-12-05 19:14 750关于spring自动检测组件的使用方式网上太多了,而且也不 ... -
spring组件扫描<context:component-scan/>使用详解 (
2012-11-28 08:57 732关于spring自动检测组件的使用方式网上太多了,而且也不 ... -
static class 静态类(Java)
2012-11-23 20:20 904一般情况下是不可以用static 修饰类的。 ... -
java jvm 调优实战
2012-11-13 10:01 8291.eclipse 打印gc日志 eclipse根目录 ... -
Zookeeper的一致性协议:Zab
2012-11-04 16:14 1263Zookeeper使用了一种称为 ... -
浅谈java内存模型
2012-10-30 19:29 874不同的平台,内存模� ... -
JVM分代垃圾回收策略的基础概念
2012-08-15 12:43 719由于不同对象的生命周期不一样,因此在JVM的垃圾回收策略中有分 ... -
bloom filter 的Java 版
2012-07-26 21:50 912属于转贴:http://www.cnblo ...
相关推荐
总之,“线程同步方法--Metux实例”通过C++的`std::mutex`展示了如何在Metux库中实现线程安全的资源共享,这对于理解和应用多线程编程,特别是在网络编程中,具有很高的实践价值。通过深入学习和实践这个实例,...
常用的线程锁分为一下七种:volatile关键字、Lock锁、System.Threading.Interlocked原子级别操作、Monitor、Metux、ReaderWriterLock、EventWaitHandle同步事件。此次代码中包含了以上除了volatile的测试代码
互斥锁是一种用于多线程或进程同步的机制,它确保在任何时候只有一个线程或进程可以持有锁,从而防止数据竞争。在Linux内核中,互斥锁通过`mutex`结构体实现,主要函数有`mutex_init()`初始化互斥锁,`mutex_lock()`...
已包含完整的RT-Thread依赖,可直观体验RT-Thread的使用,代码方面主要未使用互斥量Mutex可能存在的问题,以及使用Mutex如何解决问题的完整示例demo。 工程方面已经集成了RT-Thread的源码,配合博文《RT-Thread 体验...
内容概要:本文详细介绍了应用于电镀生产线的西门子S7-300 PLC控制系统的程序设计、硬件配置以及调试过程中积累的实际经验。主要内容涵盖温度控制、条码记录、行车定位、故障排查等方面的技术细节。文中展示了多个关键功能模块的具体实现方法,如PID温度控制、条码数据处理、行车定位判断等,并分享了一些实用的调试技巧和注意事项。此外,还讨论了硬件配置中的重要细节,如模块地址分配、网络拓扑设计等。 适合人群:从事自动化控制领域的工程师和技术人员,尤其是对PLC编程有一定基础的人群。 使用场景及目标:适用于需要深入了解和掌握电镀生产线自动化控制技术的专业人士。目标是帮助读者理解S7-300 PLC在电镀生产线中的具体应用,提高实际项目的开发效率和可靠性。 其他说明:文章不仅提供了详细的程序代码示例,还分享了许多来自一线的真实案例和实践经验,对于解决实际工程中的问题具有很高的参考价值。
内容概要:本文详细介绍了使用COMSOL Multiphysics进行固体超声导波的二维仿真过程。作者通过建立一个10mm×100mm的铝板模型,应用汉宁窗调制的5周期200kHz正弦激励信号,研究了超声导波在铝板中的传播特性及其模式转换现象。文中涵盖了从模型构建、材料参数设置、网格划分、边界条件设定、激励信号施加到求解设置以及结果分析的完整流程。特别强调了汉宁窗调制的作用,即减少频谱泄漏并提高信号质量。 适合人群:从事超声检测、材料科学、物理学等相关领域的研究人员和技术人员,尤其是那些希望深入了解COMSOL仿真工具及其在超声导波研究中应用的人群。 使用场景及目标:适用于需要精确模拟超声波在固体介质中传播的研究项目,旨在验证理论预测、优化实验设计、评估不同材料和结构对超声波的影响。此外,还可以用于教学目的,帮助学生掌握COMSOL软件的操作方法和超声导波的基础知识。 其他说明:文中提供了详细的参数设置指导和代码片段,有助于读者快速复现仿真过程。同时,作者分享了一些实用技巧,如如何正确设置网格大小、选择合适的窗函数等,以确保仿真结果的准确性。
离职人员分析仪表盘.xlsx
内容概要:本文详细介绍了如何利用LabVIEW搭建一个多功能的虚拟函数信号发生器及其信号分析功能。首先,文章展示了如何通过LabVIEW的前面板和程序框图创建各种常见波形(如正弦波、方波、三角波等),并深入探讨了波形生成的具体实现方法,包括三角波的周期性和斜率计算、白噪声的生成以及自定义公式的解析。接着,文章讨论了信号处理的关键技术,如自相关分析、频谱分析、积分和微分运算,并提供了具体的实现代码和注意事项。此外,文中还分享了一些实用的经验和技术细节,如避免频谱泄漏的方法、处理多频波的技术、防止内存泄漏的措施等。 适用人群:从事信号处理、电子工程、自动化控制等领域的工作技术人员,尤其是那些熟悉或希望学习LabVIEW编程的人士。 使用场景及目标:适用于实验室环境或教学环境中,用于替代传统物理信号发生器进行信号生成和分析实验。主要目标是提高信号生成和分析的灵活性和便捷性,减少对昂贵硬件设备的依赖。 其他说明:本文不仅提供了详细的代码示例,还分享了许多作者在实践中积累的经验教训,帮助读者更好地理解和应用LabVIEW进行信号处理。
线性代数
大雾至尊版V56泛滥无密码.zip
员工生日关怀方案
试用期情况跟踪表.xls
员工激励机制与技巧
员工晋升的自我评价.doc
基于51单片机protues仿真的多功能婴儿车控制器(仿真图、源代码、AD原理图) 该设计为51单片机protues仿真的多功能婴儿车控制器,实现温湿度,音乐,避障,声音监测控制; 1、温湿度检测,婴儿尿湿时会有提醒。 2、声音检测,当婴儿啼哭时也会有提醒。 3、小车避障,小车遇到障碍会后退左转。 4、音乐播放。 5、仿真图、源代码、AD原理图;
内容概要:本文档详细介绍了计算机求职笔试的内容与解答,涵盖编程语言基础、数据结构与算法、编程实践与调试、系统设计与软件工程以及综合题型与开放题五个方面。编程语言基础部分强调了语法规则、数据类型与运算符、面向对象编程的核心概念;数据结构与算法部分讲解了常见数据结构(如线性结构、树与图、哈希表)和高频算法(如排序算法、动态规划、递归与回溯);编程实践与调试部分关注编码能力和调试技巧;系统设计与软件工程部分探讨了设计模式、模块化设计、数据库与网络知识;综合题型与开放题部分则提供了场景题和逻辑思维题的示例。最后给出了备考建议,包括知识体系构建、刷题策略和模拟实战的方法。 适合人群:即将参加计算机相关职位笔试的求职者,特别是对编程语言、数据结构、算法设计有初步了解的应届毕业生或初级工程师。 使用场景及目标:①帮助求职者系统复习计算机基础知识,提升笔试通过率;②通过例题和解答加深对编程语言、数据结构、算法的理解;③提供模拟实战环境,提高时间管理和抗压能力。 阅读建议:建议按照文档提供的知识体系顺序进行系统复习,重点攻克高频题型,利用在线平台刷题练习,并结合实际项目经验进行综合应用,同时注意时间管理和抗压能力的训练。
SecureCRT安装包
物流业人才流失与紧缺现象的对策研究
招聘渠道费用仪表盘P10.pptx
内容概要:本文详细介绍了五相永磁同步电机在Simulink环境下的PI双闭环SVPWM矢量控制建模过程及其优化方法。首先阐述了五相电机相比三相电机的优势,如更小的转矩脉动和更强的容错能力。接着探讨了复杂的Simulink模型搭建,涉及电机本体模块、坐标变换模块、SVPWM模块和PI调节器模块等多个组件。文中提供了具体的Clark变换和PI调节器的代码示例,解释了双闭环控制的工作原理,并详细描述了SVPWM与十扇区划分的具体实现方式。最后展示了模型的性能表现,包括良好的波形质量和快速的动态响应特性。 适合人群:从事电机控制领域的研究人员和技术人员,尤其是对五相永磁同步电机和Simulink建模感兴趣的读者。 使用场景及目标:适用于希望深入了解五相永磁同步电机控制原理并掌握具体实现方法的研究人员和技术人员。目标是帮助读者理解五相电机的特殊性和复杂性,掌握PI双闭环SVPWM矢量控制的建模技巧,提高电机控制系统的设计水平。 其他说明:文章不仅提供了理论知识,还包括了大量的代码片段和实践经验分享,有助于读者更好地理解和应用相关技术。