对java软件开发有一定兴趣的朋友们,不知道是否来了解过信号量的使用场景呢?知道一般信号量都会在哪些地方使用吗?跟小编一起来看看吧。
一般来说开发中经常会遇到如下几种业务场景:
问题1: 某一个界面需要同时发多个请求,全部请求都成功后再一起刷新界面;
问题2: 多个请求必须按照一定顺序执行;
问题3: 控制线程开启的数量。
信号量比较常用的三个方法如下所示:
dispatch_semaphore_create:创建一个信号量(semaphore)
dispatch_semaphore_signal:信号通知,即让信号量+1
dispatch_semaphore_wait:等待,直到信号量大于0时,即可操作,同时将信号量-1
问题1的解决方案示例:
dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //请求1 dispatch_semaphore_t sema = dispatch_semaphore_create(0); [网络请求:{ 成功:dispatch_semaphore_signal(sema); 失败:dispatch_semaphore_signal(sema); }]; dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); }); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //请求2 dispatch_semaphore_t sema = dispatch_semaphore_create(0); [网络请求:{ 成功:dispatch_semaphore_signal(sema); 失败:dispatch_semaphore_signal(sema); }]; dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); }); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //请求3 dispatch_semaphore_t sema = dispatch_semaphore_create(0); [网络请求:{ 成功:dispatch_semaphore_signal(sema); 失败:dispatch_semaphore_signal(sema); }]; dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ //界面刷新 NSLog(@"任务均完成,刷新界面"); });
问题2解决方案示例如下:
//第一步:获取token NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ [self task_1]; }]; //第二步:上传七牛 NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ [self task_2]; }]; //第三步:图片地址上传服务器 NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{ [self task_3]; }]; //设置依赖 [operation2 addDependency:operation1]; //任务二依赖任务一 [operation3 addDependency:operation2]; //任务三依赖任务二 //创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; [queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO]; - (void)task_1 { //创建信号量并设置计数默认为0 dispatch_semaphore_t sema = dispatch_semaphore_create(0); [self.entityRequest postGetQiNiuTokenSuccess:^(NS_M_RequestOutput *json) { //请求成功 计数+1操作 dispatch_semaphore_signal(sema); } failure:^(NSString *msg) { //请求失败 计数+1操作 dispatch_semaphore_signal(sema); } error:^(NSError *error) { //请求异常 计数+1操作 dispatch_semaphore_signal(sema); }]; //若计数为0则一直等待 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); } - (void)task_2 { //创建信号量并设置计数默认为0 dispatch_semaphore_t sema = dispatch_semaphore_create(0); [self.entityRequest postGetQiNiuTokenSuccess:^(NS_M_RequestOutput *json) { //请求成功 计数+1操作 dispatch_semaphore_signal(sema); } failure:^(NSString *msg) { //请求失败 计数+1操作 dispatch_semaphore_signal(sema); } error:^(NSError *error) { //请求异常 计数+1操作 dispatch_semaphore_signal(sema); }]; //若计数为0则一直等待 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); } - (void)task_3 { //创建信号量并设置计数默认为0 dispatch_semaphore_t sema = dispatch_semaphore_create(0); [self.entityRequest postGetQiNiuTokenSuccess:^(NS_M_RequestOutput *json) { //请求成功 计数+1操作 dispatch_semaphore_signal(sema); } failure:^(NSString *msg) { //请求失败 计数+1操作 dispatch_semaphore_signal(sema); } error:^(NSError *error) { //请求异常 计数+1操作 dispatch_semaphore_signal(sema); }]; //若计数为0则一直等待 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); }
问题3解决方案示例如下:
dispatch_semaphore_t sema = dispatch_semaphore_create(5);
for (100次循环操作) { dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 操作 dispatch_semaphore_signal(sema); }); }
那么以上就是有关信号量的使用场景的所有内容了,还想了解更多java常见问答的朋友,可以关注本站消息获取更多精彩内容哦。
推荐阅读: