- (NSString *)myString {
  @synchronized(self) {
    return [[myString retain] autorelease];
  }
}

转换1:

- (NSString *)myString {
  NSString *retval = nil;
  pthread_mutex_t *self_mutex = LOOK_UP_MUTEX(self);
  pthread_mutex_lock(self_mutex);
  retval = [[myString retain] autorelease]; //Exception-Safe need
  pthread_mutex_unlock(self_mutex);
  return retval;
}

转换2:

// needs #import mm/mm-sync.h
- (NSString*) myString {
  id retVal = nil;
  mm_sync_enter(self);
  @try {
    retVal = [[myString retain] autorelease];
  }
  @catch(NSException* ex) {
  }
  @finaly {
    mm_sync_exit(self);
  }
  return retVal;
}

更高效的是spin_lock,可以对需要并发共享的数据进行非常精细的控制。但如何做到异常安全,需要非常小心。

GCD

queue是任务存取的队列,FIFO。有两种类型的任务队列:并行和串行。

GCD只提供入队的api,即dispatch_[a]sync、dispatch_group_async、dispatch_barrier_async,出队的api由GCD library自己实现,大致的实现逻辑是这样的:在多个/单个线程中,循环出队,执行任务。

由于async在处理同步时较为复杂,GCD提供了dispatch_group_async、dispatch_barrier_async来完成异步任务的时序同步。

dispatch_barrier_async保证barrier之前的async task执行结束后,barrier之后的任务才开始执行:

dispatch_queue_t queue = dispatch_queue_create("me.xjump.concurrent_barrier", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
    [NSThread sleepForTimeInterval:2];
    NSLog(@"dispatch_async1");
});
dispatch_async(queue, ^{
    [NSThread sleepForTimeInterval:4];
    NSLog(@"dispatch_async2");
});
dispatch_barrier_async(queue, ^{
    NSLog(@"dispatch_barrier_async");
    [NSThread sleepForTimeInterval:4];
});
dispatch_async(queue, ^{
    [NSThread sleepForTimeInterval:1];
    NSLog(@"dispatch_async3");
});

group_async可以实现一批async task执行结束后,在notify回调中进行批任务完成处理:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
    [NSThread sleepForTimeInterval:1];
    NSLog(@"group1");
});
dispatch_group_async(group, queue, ^{
    [NSThread sleepForTimeInterval:2];
    NSLog(@"group2");
});
dispatch_group_async(group, queue, ^{
    [NSThread sleepForTimeInterval:3];
    NSLog(@"group3");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"updateUi");
});
dispatch_release(group);

避免在main线程中调用,但需要同步等待结果:

dispatch_semaphore_t sema = dispatch_semaphore_create(0);
// check sema is nil??
dispatch_async(dispatch_get_global_queue(0, 0), ^{
  @try {
     result = [service callSomeMethod];
  }
  @catch (NSException *exception) {
     NSLog(@"%@", exception.reason);
  }
  @finally {
     dispatch_semaphore_signal(sema);
  }
});
// dispatch_time( dispatch_time_t when, int64_t delta);
// dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, 1000*1000*3);
// dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
// dispatch_release(sema);
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(60.0 * NSEC_PER_SEC));
if(0==dispatch_semaphore_wait(sema, timeout)){
  dispatch_release(sema);
}

在非main线程处理业务,处理结束后更新UI:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
    // biz start ...
    // bala bala
    // biz end
    dispatch_async(dispatch_get_main_queue(), ^(void){
        // update UI
    });
});

关于global queue的并发特性:

DISPATCH_QUEUE_PRIORITY_BACKGROUND:并行队列,任务会串行执行;
DISPATCH_QUEUE_PRIORITY_LOW:并行队列,任务会串行执行;
DISPATCH_QUEUE_PRIORITY_DEFAULT:并行队列,任务会串行执行;
DISPATCH_QUEUE_PRIORITY_HIGH:并行队列,任务会串行执行;
BACKGROUND, LOW, DEFAULT, HIGH 分别代表不同的优先级,高优先级队列中的任务会优先调度。
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN

而对于main queue来说,只能由main线程获取队列任务,然后进行调度执行,所以是串行的。

当main、global这两个任务队列不能满足要求时,还可以创建自定义的队列。

创建concurrent queue:

dispatch_queue_t q = dispatch_queue_create("me.xjump.concurrent_queue", DISPATCH_QUEUE_CONCURRENT);

创建serial queue:

dispatch_queue_t q = dispatch_queue_create("me.xjump.serial_queue", DISPATCH_QUEUE_SERIAL);

从GCD api手册上了看,有dispatch_get_global_queue,但没有获取自定义的queue的api,这个时候,可以使用Singleton和map来实现。

关于GCD,线程池实际上是共享的,看下图:

参考:

https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref

http://blog.csdn.net/totogo2010/article/details/8016129

http://stackoverflow.com/questions/19822700/difference-between-dispatch-async-and-dispatch-sync-on-serial-queue

http://stackoverflow.com/questions/16283652/understanding-dispatch-async

http://mmcn.io/issue-2-1/

http://opensource.apple.com/source/mm4/mm4-437.1/runtime/mm-sync.m

http://www.kuro5hin.org/story/2011/1/21/193921/656

http://www.mm.io/issue-2/thread-safe-class-design.html

http://mmcn.io/issue-2-4/