- 浏览: 188180 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
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 832在以后的开发项目时可以适当使用工具进行程序检查: 1、F ... -
WorkbookFactory 找不到
2013-11-08 10:46 1000在最近的POI版本中,poi-3.9.jar包中找不到Work ... -
记一次JVM GC日志分析
2013-03-08 21:36 1749这几天在准备升级JDK版本到1.6,对目前线上JVM(版 ... -
Eclipse 相同变量的高亮 及颜色
2013-02-18 17:26 1652在Eclipse/MyEclipse中如果不小心把变量的高 ... -
java jstack dump 线程 介绍 解释
2013-02-05 15:52 1213hi,all: 最近抽时间把JVM运行 ... -
[转载]JDMK 基本JMX配置( html adaptor)
2013-01-07 13:37 1731原文地址: JDMK 基本JMX配置( html adap ... -
JAVA中的继承分析
2012-12-27 11:43 5163为什么写这篇博客,之前对继承的理解知识大体理论上,最近 ... -
JVM学习之:虚拟机中的运行时栈帧总结(二)
2012-12-12 19:46 843在 JVM学习之:虚拟机 ... -
JVM学习之:虚拟机中的运行时栈帧总结(一)
2012-12-12 19:45 871每 个人都知道,各种各样的动画视频,都是由一帧一帧图片连 ... -
JAVA字符串占位符
2012-12-06 08:24 3224包 java.text.MessageFormat java ... -
copy项目是容易出现的错误--webAppRootKey错误
2012-12-05 21:18 729Tomcat 发布多个项目时抛的webAppRootKey错误 ... -
web.xml配置总结
2012-12-05 20:50 672一、关于webAppRootKey的定义 默 ... -
spring组件扫描<context:component-scan/>使用详解
2012-12-05 19:14 734关于spring自动检测组件的使用方式网上太多了,而且也不 ... -
spring组件扫描<context:component-scan/>使用详解 (
2012-11-28 08:57 717关于spring自动检测组件的使用方式网上太多了,而且也不 ... -
static class 静态类(Java)
2012-11-23 20:20 876一般情况下是不可以用static 修饰类的。 ... -
java jvm 调优实战
2012-11-13 10:01 8151.eclipse 打印gc日志 eclipse根目录 ... -
Zookeeper的一致性协议:Zab
2012-11-04 16:14 1232Zookeeper使用了一种称为 ... -
浅谈java内存模型
2012-10-30 19:29 841不同的平台,内存模 ... -
JVM分代垃圾回收策略的基础概念
2012-08-15 12:43 701由于不同对象的生命周期不一样,因此在JVM的垃圾回收策略中有分 ... -
bloom filter 的Java 版
2012-07-26 21:50 886属于转贴: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 体验...
只需要用一张图片素材文档选择器.zip
浙江大学842真题09-24 不含答案 信号与系统和数字电路
无标题baci和jbaci
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
实体商品销售源码最新优化.zip
内容概要:本文档详细介绍了戴尔存储MD1400机柜的安全注意事项、电源指示灯解释、故障排除方法以及硬件维护步骤,包括卸下和安装直流电源设备、硬盘驱动器和背板的具体操作流程。 适用人群:IT运维人员、数据中心管理员和技术支持工程师。 使用场景及目标:在维护和管理戴尔存储MD1400机柜时作为参考指南,确保正确安装和故障排查,避免安全隐患和设备损坏。 其他说明:文档提供了丰富的图文指导,帮助使用者更好地理解和执行相关操作。
PyClass 课程计划Noisebridge Python 课程每周一晚上 7 点至 9 点(太平洋时间)在旧金山 Noisebridge 二楼电子室举行。自 2024 年 8 月起,该课程目前暂停。请参阅 wiki 页面了解更多信息。本课程免费!如果您希望捐款,请捐赠给 Noisebridge。建议捐款15 美元、50 美元、200 美元以上建议每月捐款每月 10 美元、20 美元、40 美元、80 美元以上所有 Python 课程均遵循Noisebridge 反骚扰政策、 Noisebridge 冲突解决指南和 recurse.org 社交规则课后,我们欢迎您提供反馈! 在此提交表格内容课程课程描述新生阅读迭代次数Noisebridge Python 课程至少早在 2015 年就已经存在,拥有许多不同的讲师和版本。从 2017 年到 2018 年,该课程似乎由Jared Garst负责。(?)。从 2023 年到 2024 年,该课程由Travis Briggs负责。如果您有其他关于此类历史的信息想要分享,请在此处创建 PR、
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
万达广场作为城市综合体的代表,在中国各地的地理分布数据集覆盖了2006至2021年。这些数据详细记录了万达广场的多个关键指标,包括项目名称、项目信息、具体地点、开业时间、商业面积以及精确的经度和纬度。万达广场不仅是商业地产开发的先行者,还以其成熟的商业模式、完善的产业链和丰富的商业资源,在全国范围内形成了独立的大型商圈。这些综合体集购物、餐饮、文化、娱乐等多种功能于一体,对提升城市商业档次、增加就业岗位、创造税收以及丰富群众消费需求等方面产生了显著的社会效益。数据集提供了420条样本,为研究中国区域经济发展特征及其未来趋势提供了宝贵的信息资源。
正在月下弹琴的古装美女flash场景动画.zip
理光 MP C8003 是一款彩色激光多功能数码复合机。 【基础性能】 打印复印速度:黑白和彩色打印 / 复印速度均可达 80 页每分钟,能够快速高效地完成大量文档的输出任务,有效提高工作效率 分辨率:拥有 1200x4800dpi 的高分辨率,可输出色彩鲜艳、细节丰富、图像清晰的文档和图像,满足专业级的打印和复印需求,尤其适合对色彩精度要求较高的设计图纸、宣传资料等文件的输出 首张输出时间:黑白首张复印时间为 4.7 秒,彩色首张复印时间为 6.3 秒,在启动打印或复印任务时无需长时间等待,可迅速响应,进一步提升工作效率 纸张容量:标准配置的纸张容量为单 2500 页抽屉和双 550 页抽屉,还可通过扩展将纸张容量从 3700 页提升至 8100 页,能够满足不同规模的打印任务需求,减少纸张添加的频率 【功能多样性】 多功能一体:集复印、打印、扫描、传真功能于一身,可满足办公室多样化的文档处理需求,一台设备即可替代多台单一功能的设备,节省空间和成本 扫描功能:具备高速扫描能力,可通过多种扫描至选项将原件扫描并以电子形式分发,支持将扫描后的文件直接发送至个人移动设备
《The Annotated Transformer》环境配置
深度学习大作业基于resnet50和vgg16卷积神经网络的汉字书法识别项目源码+训练集+测试集 操作步骤 将下载的训练集和测试集,解压到工程中 运行对应的data.py文件,进行转录,将原始数据集转录为numpy矩阵,生成data.npy及label.npy 运行对应的train.py进行训练 运行test.py使用训练完成的网络测试。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手
代码