修正信号量
来源:互联网 发布:傲剑紫霞升级数据大全 编辑:程序博客网 时间:2024/04/30 06:07
现在考虑Semaphore.java。看起来我们能通过给三个方法加上 synchronized标记,
来修正这个问题,就像这样:
//: c13:SynchronizedSemaphore.java
// Colliding over shared resources
public class SynchronizedSemaphoreextendsSemaphore
{
private volatile int semaphore = 0;
public synchronized boolean available() {
return semaphore == 0;
}
public synchronized void acquire() { ++semaphore; }
public synchronized void release() { --semaphore; }
public InvariantState invariant() {
intval = semaphore;
if(val== 0 || val == 1)
return new InvariantOK();
else
return new InvariantFailure(newInteger(val));
}
public static void main(String[] args) throws
Exception {
SynchronizedSemaphore sem =new
SynchronizedSemaphore();
newSemaphoreTester(sem);
newSemaphoreTester(sem);
newInvariantWatcher(sem).join();
}
} ///:~
首先,SynchronizedSemaphore类就显得很奇怪:它是从 Semaphore类继承而来,且
所有被重载的方法都标记为 synchronized,但这些方法的基类版本却不是。Java 并不
允许你在重载的时候改变方法的签名,但这却没有产生出错信息。这是因为 synchronized
关键字不属于方法签名的一部分,所以你才能把它加进来,而它也并不局限于重载。
从Semaphore类继承的原因是为了重用SemaphoreTester类。当你运行程序的时候你会
发现程序还是会产生InvariantFailure错误。
为什么会失败呢?当线程检测到Semaphore可用时,即调用available( )并且返回为真
的时候,对象上的锁已经被释放。这时,另一个线程可能会冲进来,并在前一个线程增加
semaphore值的时候抢先增加。同时,前一个线程还在假设Semaphore对象是可用的,所
以会继续向前并盲目的进入acquire()方法,这就使对象处于不稳定的状态。这只不过
是并发编程首要规则的又一次教训而已:永远不要做任何假设。
这个问题的唯一解决方案是,把测试可用性操作和获取操作作为一个单一的原子操作,这
也就是synchronized关键字与对象的锁协作所共同提供的功能。也就是说,Java的锁和
synchronized关键字属于内置的信号量机制,所以你不必自己再去发明一个。
- 修正信号量
- 修正
- 修正
- 修正
- 信号量
- 信号量
- 信号量
- 信号量
- 信号量
- 信号量
- 信号量
- 信号量
- 信号量
- 信号量
- 信号量
- 信号量
- 信号量
- 信号量
- 保时捷赛-李娜负莎娃失赛季第2冠群
- 程序里wstring,string和CString的Buffer里到底存的是什么(菜鸟问题)
- C++知识点汇总一
- hadoop学习过程-2013.08.30.1--按照网页内容搜索出网页01--确定网页来源
- 上班八小时的习惯
- 修正信号量
- Devexpress XtraReports报表教程
- 取石子游戏(博弈类)
- 怎么恢复损坏后的undo 表空间(一)
- 使用润乾报表的心得
- Java Se 程序运用整合归纳
- createserver(oracle)
- AES加解密(java)
- poj_2155 Matrix