原子操作 0.9.0

原子操作 0.9.0

测试已测试
Lang语言 Obj-CObjective C
许可证 MIT
Released最新版本2015年4月

Bruno de Carvalho 维护。



用于在 compare-and-set 原语封装,使用 libkern/OSAtomic.h 软件包中的 Foundation 类型。

  • AtomicBoolean:对 BOOL 标志的原子封装
  • AtomicInteger:对 NSInteger(32 或 64位,取决于编译_arch_ 架构)的原子封装,具有额外的计数语义(add-and-getget-and-add
  • AtomicReference:对 NSObject 的原子封装(见下面的“单个请求”示例)

使用方法

所有原子类都公开一个通用接口

  • getValue:setValue: 是简单的变量读写操作,保证原子性,而 HOPAtomicReference 除外 —— 因为它处理对象,这需要调整保留计数。操作仍然是原子性的,但对于调用者来说,它们在底层不一定原子性。

  • compareTo:andSetValue: 如果当前值匹配预期值,则原子性地设置新值。如果成功,返回 YES,否则返回 NO

  • getAndSetValue: 原子性地更新底层值,返回旧值。

示例

使用 AtomicInteger 的快速失败节流器

@implementation Throttler {
  HOPAtomicInteger *_counter;
  NSInteger _limit;
}

- (instancetype)initWithLimit:(NSInteger)limit {
  self = [super init];
  if (self != nil) {
    NSParameterAssert(limit > 0);
    _counter = [[HOPAtomicInteger alloc] initWithValue:0];
    _limit = limit;
  }
  return self;
}

// Returns YES if executed, NO otherwise
- (BOOL)throttledExec:(void (^)())block {
  if ((block == nil) || (_limit <= 0) return YES;

  if ([_counter incrementAndGetValue] > _limit) {
    [_counter decrementAndGetValue];
    return YES;
  }

  block()

  [_counter decrementAndGetValue];
  return NO;
}
@end
// Throttler *_t
BOOL executed = [_t throttledExec:^{
  // Critical section
}];

if (!executed) {
  NSLog(@"Resource unavailable");
}

单一请求网关

@implementation SingleRequestLauncher {
  HOPAtomicReference *_ref;
}

- (instancetype)init {
  self = [super init];
  if (self != nil) {
    // Reference never changes, only what it holds.
    _ref = [[HOPAtomicReference alloc] init];
  }
  return self;
}

- (BOOL)launchRequest:(...)... {
  id request = // create the request
  if ([_ref compareTo:nil andSetObject:request]) {
    [request start];
    return YES;
  }

  return NO;
}

- (BOOL)cancelActiveRequest {
  id current = [_ref getAndSetObject:nil];
  if (current == nil) return NO;

  [current cancel];
  return YES;
}

@end

注意:上面代码假设请求创建在请求完成时会调用 [_ref setObject:nil],无论是通过成功还是失败。