多线程 & 网络

iOS多线程:GCD进阶篇

2020-04-12  本文已影响0人  码小菜
别墅

目录
一,dispatch_after
二,dispatch_once
三,dispatch_apply
四,dispatch_group
五,dispatch_semaphore
六,dispatch_barrier

一,dispatch_after

1,使用

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"1");
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"2");
    });
    
    NSLog(@"3");
}

// 打印
07:04:14.185538+0800 Demo[82191:12753573] 1
07:04:14.186943+0800 Demo[82191:12753573] 3
07:04:17.185982+0800 Demo[82191:12753573] 2

2,说明

二,dispatch_once

1,使用

- (void)viewDidLoad {
    [super viewDidLoad];
    
    for (int i = 0; i < 5; i++) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            NSLog(@"%d", i + 1);
        });
    }
}

// 打印
1

2,说明

三,dispatch_apply

1,使用

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"begin");
    
    NSArray *array = @[@"1", @"2", @"3"];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_apply(array.count, queue, ^(size_t index) {
        NSLog(@"%@---%@", array[index], [NSThread currentThread]);
    });
    
    NSLog(@"end");
}

// 打印
begin
2---<NSThread: 0x6000019498c0>{number = 3, name = (null)}
3---<NSThread: 0x60000194a080>{number = 4, name = (null)}
1---<NSThread: 0x600001916100>{number = 1, name = main}
end

2,说明

四,dispatch_group

1,使用

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"begin---%@", [NSThread currentThread]);
    
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_group_async(group, queue, ^{
        NSLog(@"任务1---%@", [NSThread currentThread]);
        sleep(1.0);
    });

    dispatch_group_async(group, queue, ^{
        NSLog(@"任务2---%@", [NSThread currentThread]);
        sleep(1.0);
    });

    dispatch_group_async(group, queue, ^{
        NSLog(@"任务3---%@", [NSThread currentThread]);
        sleep(1.0);
    });

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"group中的任务都已经执行完毕---%@", [NSThread currentThread]);
    });
    
    NSLog(@"end---%@", [NSThread currentThread]);
}

// 打印
begin---<NSThread: 0x60000289e800>{number = 1, name = main}
end---<NSThread: 0x60000289e800>{number = 1, name = main}
任务1---<NSThread: 0x6000028cc980>{number = 4, name = (null)}
任务3---<NSThread: 0x6000028c6040>{number = 3, name = (null)}
任务2---<NSThread: 0x6000028c2100>{number = 5, name = (null)}
group中的任务都已经执行完毕---<NSThread: 0x60000289e800>{number = 1, name = main}
- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"begin---%@", [NSThread currentThread]);
    
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_group_async(group, queue, ^{
        NSLog(@"任务1---%@", [NSThread currentThread]);
        sleep(1.0);
    });

    dispatch_group_async(group, queue, ^{
        NSLog(@"任务2---%@", [NSThread currentThread]);
        sleep(1.0);
    });

    dispatch_group_async(group, queue, ^{
        NSLog(@"任务3---%@", [NSThread currentThread]);
        sleep(1.0);
    });

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    NSLog(@"group中的任务都已经执行完毕---%@", [NSThread currentThread]);
    
    NSLog(@"end---%@", [NSThread currentThread]);
}

// 打印
begin---<NSThread: 0x6000029fcbc0>{number = 1, name = main}
任务2---<NSThread: 0x6000029a1780>{number = 6, name = (null)}
任务1---<NSThread: 0x60000298d400>{number = 7, name = (null)}
任务3---<NSThread: 0x6000029b3b40>{number = 4, name = (null)}
group中的任务都已经执行完毕---<NSThread: 0x6000029fcbc0>{number = 1, name = main}
end---<NSThread: 0x6000029fcbc0>{number = 1, name = main}
- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"begin---%@", [NSThread currentThread]);
    
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    // group中的任务数+1
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"任务1---%@", [NSThread currentThread]);
        sleep(1.0);
        // group中的任务数-1
        dispatch_group_leave(group);
    });

    // group中的任务数+1
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"任务2---%@", [NSThread currentThread]);
        sleep(1.0);
        // group中的任务数-1
        dispatch_group_leave(group);
    });

    // group中的任务数+1
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        NSLog(@"任务3---%@", [NSThread currentThread]);
        sleep(1.0);
        // group中的任务数-1
        dispatch_group_leave(group);
    });

    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"group中的任务数为0---%@", [NSThread currentThread]);
    });
    
    NSLog(@"end---%@", [NSThread currentThread]);
}

// 打印
begin---<NSThread: 0x600002d960c0>{number = 1, name = main}
end---<NSThread: 0x600002d960c0>{number = 1, name = main}
任务1---<NSThread: 0x600002dfb100>{number = 7, name = (null)}
任务3---<NSThread: 0x600002ddbc40>{number = 4, name = (null)}
任务2---<NSThread: 0x600002dc3400>{number = 5, name = (null)}
group中的任务数为0---<NSThread: 0x600002d960c0>{number = 1, name = main}

2,说明

五,dispatch_semaphore

1,使用

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"1---%@", [NSThread currentThread]);
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(1.0);
        NSLog(@"2---%@", [NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    NSLog(@"3---%@", [NSThread currentThread]);
}

// 打印
1---<NSThread: 0x600002491080>{number = 1, name = main}
2---<NSThread: 0x6000024c0e80>{number = 5, name = (null)}
3---<NSThread: 0x600002491080>{number = 1, name = main}
- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 最大并发数为2
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);

    for (int i = 0; i < 10; i++) {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

            sleep(1.0);
            NSLog(@"%d---%@", i + 1, [NSThread currentThread]);

            dispatch_semaphore_signal(semaphore);
        });
    }
}

// 打印(同时只打印两次)
06:43:09.900220+0800 Demo[26085:16867256] 1---<NSThread: 0x6000006e2140>{number = 6, name = (null)}
06:43:09.900238+0800 Demo[26085:16867255] 2---<NSThread: 0x6000006fff80>{number = 5, name = (null)}
06:43:10.903011+0800 Demo[26085:16867239] 3---<NSThread: 0x6000006e7900>{number = 3, name = (null)}
06:43:10.903022+0800 Demo[26085:16867243] 4---<NSThread: 0x6000006c7c40>{number = 8, name = (null)}
06:43:11.906306+0800 Demo[26085:16867240] 5---<NSThread: 0x6000006b8600>{number = 4, name = (null)}
06:43:11.906350+0800 Demo[26085:16867259] 6---<NSThread: 0x6000006c7f40>{number = 9, name = (null)}
06:43:12.907370+0800 Demo[26085:16867261] 7---<NSThread: 0x6000006c7f80>{number = 11, name = (null)}
06:43:12.907366+0800 Demo[26085:16867260] 8---<NSThread: 0x6000006cf140>{number = 10, name = (null)}
06:43:13.912833+0800 Demo[26085:16867262] 9---<NSThread: 0x6000006c7d00>{number = 13, name = (null)}
06:43:13.912925+0800 Demo[26085:16867263] 10---<NSThread: 0x6000006caac0>{number = 12, name = (null)}
@interface ViewController ()
@property (nonatomic, assign) int ticket;
@property (nonatomic, strong) dispatch_semaphore_t semaphore;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.ticket = 10;
    self.semaphore = dispatch_semaphore_create(1);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 5; i++) {
            [self saleTicket];
        }
    });
}
- (void)saleTicket {
    dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER);
    
    int oldTicket = self.ticket;
    sleep(0.3);
    oldTicket -= 1;
    self.ticket = oldTicket;
    NSLog(@"剩余%d张票---%@", self.ticket, [NSThread currentThread]);
    
    dispatch_semaphore_signal(self.semaphore);
}
@end

// 打印
剩余9张票---<NSThread: 0x60000324a980>{number = 3, name = (null)}
剩余8张票---<NSThread: 0x600003253b80>{number = 5, name = (null)}
剩余7张票---<NSThread: 0x60000324a980>{number = 3, name = (null)}
剩余6张票---<NSThread: 0x600003253b80>{number = 5, name = (null)}
剩余5张票---<NSThread: 0x60000324a980>{number = 3, name = (null)}
剩余4张票---<NSThread: 0x600003253b80>{number = 5, name = (null)}
剩余3张票---<NSThread: 0x60000324a980>{number = 3, name = (null)}
剩余2张票---<NSThread: 0x600003253b80>{number = 5, name = (null)}
剩余1张票---<NSThread: 0x60000324a980>{number = 3, name = (null)}
剩余0张票---<NSThread: 0x600003253b80>{number = 5, name = (null)}

2,说明

1>如果信号量的值大于0,就将值-1并往下执行

2>如果信号量的值等于0,就让线程休眠并等待信号

3>收到信号后会唤醒线程并重新判断信号量的值

将信号量的值+1并发送信号

六,dispatch_barrier

1,使用

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"begin---%@", [NSThread currentThread]);
    __block int data = 99;
    dispatch_queue_t queue = dispatch_queue_create("MyConcurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    
    dispatch_async(queue, ^{
        sleep(1.0);
        NSLog(@"读1---%d---%@", data, [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        sleep(1.0);
        NSLog(@"读2---%d---%@", data, [NSThread currentThread]);
    });
    
    dispatch_barrier_async(queue, ^{
        sleep(1.0);
        data = 100;
        NSLog(@"写---%@", [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        sleep(1.0);
        NSLog(@"读3---%d---%@", data, [NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{
        sleep(1.0);
        NSLog(@"读4---%d---%@", data, [NSThread currentThread]);
    });
    
    NSLog(@"end---%@", [NSThread currentThread]);
}

// 打印
07:23:15.929766+0800 Demo[34756:17878123] begin---<NSThread: 0x60000392ddc0>{number = 1, name = main}
07:23:15.930049+0800 Demo[34756:17878123] end---<NSThread: 0x60000392ddc0>{number = 1, name = main}
07:23:16.932491+0800 Demo[34756:17878203] 读1---99---<NSThread: 0x6000039719c0>{number = 3, name = (null)}
07:23:16.932491+0800 Demo[34756:17878195] 读2---99---<NSThread: 0x60000396a280>{number = 5, name = (null)}
07:23:17.938203+0800 Demo[34756:17878195] 写---<NSThread: 0x60000396a280>{number = 5, name = (null)}
07:23:18.940880+0800 Demo[34756:17878203] 读4---100---<NSThread: 0x6000039719c0>{number = 3, name = (null)}
07:23:18.940883+0800 Demo[34756:17878195] 读3---100---<NSThread: 0x60000396a280>{number = 5, name = (null)}
dispatch_barrier_sync(queue, ^{
    sleep(1.0);
    data = 100;
    NSLog(@"写---%@", [NSThread currentThread]);
});

// 打印
07:29:57.114729+0800 Demo[34807:17881597] begin---<NSThread: 0x600003e71580>{number = 1, name = main}
07:29:58.120079+0800 Demo[34807:17881637] 读1---99---<NSThread: 0x600003e4ed00>{number = 4, name = (null)}
07:29:58.120099+0800 Demo[34807:17881639] 读2---99---<NSThread: 0x600003e16a80>{number = 7, name = (null)}
07:29:59.121744+0800 Demo[34807:17881597] 写---<NSThread: 0x600003e71580>{number = 1, name = main}
07:29:59.122171+0800 Demo[34807:17881597] end---<NSThread: 0x600003e71580>{number = 1, name = main}
07:30:00.124470+0800 Demo[34807:17881637] 读4---100---<NSThread: 0x600003e4ed00>{number = 4, name = (null)}
07:30:00.124501+0800 Demo[34807:17881639] 读3---100---<NSThread: 0x600003e16a80>{number = 7, name = (null)}
dispatch_barrier_async_and_wait(queue, ^{
    sleep(1.0);
    data = 100;
    NSLog(@"写---%@", [NSThread currentThread]);
});

// 打印
10:20:10.414882+0800 Demo[35536:17905685] begin---<NSThread: 0x60000084ccc0>{number = 1, name = main}
10:20:11.421195+0800 Demo[35536:17905758] 读2---99---<NSThread: 0x60000080d0c0>{number = 4, name = (null)}
10:20:11.421212+0800 Demo[35536:17905764] 读1---99---<NSThread: 0x600000813100>{number = 3, name = (null)}
10:20:12.422726+0800 Demo[35536:17905685] 写---<NSThread: 0x60000084ccc0>{number = 1, name = main}
10:20:12.423153+0800 Demo[35536:17905685] end---<NSThread: 0x60000084ccc0>{number = 1, name = main}
10:20:13.423888+0800 Demo[35536:17905758] 读4---100---<NSThread: 0x60000080d0c0>{number = 4, name = (null)}
10:20:13.423965+0800 Demo[35536:17905764] 读3---100---<NSThread: 0x600000813100>{number = 3, name = (null)}

2,说明

1>先同时执行在dispatch_barrier函数前添加的任务

2>再单独执行在dispatch_barrier函数中添加的任务

3>然后同时执行在dispatch_barrier函数后添加的任务

1>dispatch_barrier_async:异步执行

2>dispatch_barrier_sync:同步执行,会阻塞当前线程

3>dispatch_barrier_async_and_wait:同步执行,会阻塞当前线程

上一篇 下一篇

猜你喜欢

热点阅读