1. GCD

  • Synchronous/asynchronous serial/concurrent
  • dispatch_barrier_async
  • dispatch_group
Circular waits caused by the main queue (tasks submitted in the main queue, whether synchronous or asynchronous, are executed in the main thread)
- (void)viewDidLoad {
    dispatch_sync(dispatch_get_main_queue(), ^{
        [self doSomething];
    });
}
Copy the code

- (void)viewDidLoad {
    dispatch_sync(serialQueue, ^{
        [self doSomething];
    });
}
Copy the code
The child thread by default, do not open the RunLoop performSelector: withObject: afterDelay: does not perform
- (void)viewDidLoad {
    dispatch_async(global_queue, ^{
        NSLoag(@ "1");
        [self performSelector:@selector(printLog)
              withObjec:nil
              afterDelay:0];
        NSLog(@ "3")
    });
}

-(void)printLog {
    NSLog(@ "2")}Copy the code

dispatch_barrier_async()

Use GCD to achieve multiple read single write
@interface UserCenter(a)
{
    dispatch_queue_t concurrent_queue;
    NSMutableDictionary *userCenterDic;
}
@end

@implementation UserCenter 

- (id)init 
{
    self = [super init];
    if (self) {
        concurrent_queue = dispatch_queue_create("read_write_queue", DISPATCH_QUEUE_CONCURRENT);
        userCenterDic = [NSMutableDictionary dictionary];
    }
    
    return self;
}

- (id)objectForKey:(NSString *)key 
{
    __block id obj;
    dispatch_sync(concurrent_queue, ^{
        obj = [userCeneterDic objectForKey:key];
    });
    
    return obj;
}

- (void)setObject:(id)obj forKey:(NSString *)key 
{
    dispatch_barrier_async(concurrent_queue, ^{
        [userCenterDic setObject:obj, forKey:key];
    });
}

@end
Copy the code

dispatch_group_async()

@interface GroupObject(a)
{
    dispatch_queue_t concurrent_queue;
    NSMutableArray <NSURL *> *urlArr;
}
@end

@implementation GroupObject

- (id)init 
{
    self = [super init];
    if (self) {
        concurrent_queue = dispatch_queue_create("concurrent_queue", DISPATCH_QUEUE_CONCURRENT);
        urlArr = [NSMutableArray array];
    }
    
    return self;
}

- (void)handle
{
    dispatch_group_t group = dispatch_group_create();
    
    for (NSURL *url in urlArr) {
        dispatch_group_async(group, concurrent_queue, ^{
            NSLog(@"url is %@", url);
        });
    }
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@ "complete"); })}@end
Copy the code

2, NSOperation

  • Adding task dependencies
  • Control of task execution status
  • Maximum concurrency
Task execution status
  • isReady
  • isExecuting
  • isFinished
  • isCancelled
State control

Rewrite main method, city control change task and execution completed state, and task exit rewrite start method, self control task state

The system uses KVO to remove NSOperation for isFinished = YES

3, NSThread

4. Multithreading and locking

  • NSRecursiveLock
  • NSLock
  • dispatch_semaphore_t
  1. @synchronized is typically used when creating singleton objects
  2. The atomic property keyword performs atomic operations on the modified object
  3. OSSpinLock spin lock loop wait, do not release the current resource; Lightweight data access
dispatch_semaphore_t
  • dispatch_semaphore_create(1);
  • dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
  • dispatch_semaphore_signal(semaphore);
dispatch_semaphore_create()
struct semaphore {
    int value;
    List<thread>;
}

dispatch_semaphore_wait()
{
    S.value = S.value - 1;
    if S.value < 0 then Block(S.List); => Blocked thread} dispatch_semaphore_signal() {s.value = s.value +1;
    if S.value <= 0 then wakeup(S.List);
}
Copy the code