我有一个看起来有点像这样的简单类:
@protocol Recorder
@property(BOOL) isRunning;
- (void) start;
- (void) stop;
@end
方法实现:
- (void) start {
if (running)
return;
…
running = YES;
}
- (void) stop {
if (!running)
return;
…
running = NO;
}
我开始考虑线程安全问题。目前的解决方案不是线程安全的,对吧?怎么样:
- (void) start {
@synchronized(self) {
if (running)
return;
…
running = YES;
}
}
这是正确的,前提是-stop
方法也是同步的吗?我不喜欢@synchronized
引入的额外嵌套。显式锁定会有效吗?
- (void) stop {
[startStopLock lock];
if (running)
return;
…
running = YES;
[startStopLock unlock];
}
或者我可以做到这一点吗?
enum { Running, Stopped };
NSConditionLock *startStopLock;
- (void) start {
if (![startStopLock tryLockWithCondition:Stopped])
return;
…
[startStopLock unlockWithCondition:Running];
}
此解决方案是否正确?你会以不同的方式做事吗?
答案 0 :(得分:1)
这是什么语言?你是对的,第一个版本不是线程安全的。
同步版本是线程安全的。使用显式锁定时,您需要注意不要错过早期返回路径上的解锁。
如果您可以访问锁定的xchg内在函数,则可以使用原子交换操作轻松完成。 cmpxchg也有效。
start() {
if (locked_xchg(running, YES) == YES) {
// the old value was YES, so nothing to do
return
}