信号量的使用场景有哪些?

XIAO 2020-05-10 09:48:38 java常见问答 9122

对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常见问答的朋友,可以关注本站消息获取更多精彩内容哦。

推荐阅读:

java多线程使用场景有哪些?有何作用? 

红黑树应用场景和性质都有哪些?

Redis的使用场景有哪些?Redis的数据类型有哪些?