iOS 多线程 GCD的简单使用——iOS 编码复习(七)(多线程5)
2016-03-15 16:39
501 查看
GCD最直接的三种队列,两种执行类型。
三种队列:
1、主队列,就是我们平时用到的UI主线程队列,可以调用dispatch_get_main_queue()来获得,是一个串行队列;
2、全局队列,进程中存在三个全局队列,按优先级分为:高、中(默认)、低。可以通过dispatch_get_global_queue函数传入优先级来访问队列。
3、自定义队列,就是用户自己创建的队列,通过dispatch_queue_create创建。可以通过设置属性来确定创建串行队列还是并行队列。
而我们正常敲代码的时候,也就那么几种类型:
1、串行队列,同步执行:串行队列意味着顺序执行,同步意味着不开新的线程;
2、串行队列,异步执行:串行队列意味着顺序执行,异步意味着要开新的线程;
3、并行队列,异步执行:并行队列意味着执行顺序不确定,异步执行意味着会开启线程,并行队列允许不按顺序执行
4、并行队列,同步执行:同步意味着不开线程,则还是顺序执行。
5、死锁:程序卡死。
使用多线程最应该注意的问题就是死锁了,发生死锁的最频繁的例子就是
1、主队列同步执行:
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"同步操作的线程 - %@", [NSThread currentThread]);
});
2、串行队列异步执行时,子线程用串行同步:
dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);
NSLog(@"之前线程 - %@", [NSThread currentThread]);
dispatch_async(myQueue, ^{
NSLog(@"同步操作之前线程 - %@", [NSThread currentThread]);
dispatch_sync(myQueue, ^{
NSLog(@"同步操作时线程 - %@", [NSThread currentThread]);
});
NSLog(@"同步操作之后线程 - %@", [NSThread currentThread]);
});
ok,下面直接上干货:
串行异步:
//创建一个串行队列
//其中第一个参数是标识符。第二个参数传DISPATCH_QUEUE_SERIAL或 NULL表示创建串行队列,传入
DISPATCH_QUEUE_CONCURRENT表示创建并行队列。
dispatch_queue_t myqueue =dispatch_queue_create("myqueue",NULL);
//通过一个for循环将3个很耗时的异步任务加到串行队列
for (int n=0; n<3; n++) {
dispatch_async(myqueue, ^{
for (int i=0; i<500000000; i++) {
if (i ==
0) {
NSLog(@"串行异步任务%ld ->开始%@",n,[NSThreadcurrentThread]);
}
if (i ==
499999999) {
NSLog(@"串行异步任务%ld ->完成",(long)n);
}
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1启动";
_thread1.backgroundColor = [UIColorredColor];
}
if (n==1) {
_thread2.text =@"线程2启动";
_thread2.backgroundColor = [UIColorredColor];
}
if (n==2) {
_thread3.text =@"线程3启动";
_thread3.backgroundColor = [UIColorredColor];
}
});
}
if (i==499999999) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1结束";
_thread1.backgroundColor = [UIColorcyanColor];
}
if (n==1) {
_thread2.text =@"线程2结束";
_thread2.backgroundColor = [UIColorcyanColor];
}
if (n==2) {
_thread3.text =@"线程3结束";
_thread3.backgroundColor = [UIColorcyanColor];
}
});
}
}
});
}
//
self.view.backgroundColor = [UIColoryellowColor];
串行同步:
// 创建一个串行队列
//其中第一个参数是标识符。第二个参数传DISPATCH_QUEUE_SERIAL或 NULL表示创建串行队列,传入
DISPATCH_QUEUE_CONCURRENT表示创建并行队列。
dispatch_queue_t myQueue =dispatch_queue_create("myQueue",NULL);
//通过一个for循环将3个很耗时的同步任务加到串行队列
for (NSInteger n =0; n <3; n++) {
dispatch_sync(myQueue, ^{
for (int i=0; i<500000000; i++) {
if (i ==
0) {
NSLog(@"串行同步任务%ld ->开始%@",n,[NSThreadcurrentThread]);
}
if (i ==
499999999) {
NSLog(@"串行同步任务%ld ->完成",(long)n);
}
//界面一定要主线程刷新,所以UI都是在这三个线程都执行完后统一刷新的
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1启动";
_thread1.backgroundColor = [UIColorredColor];
}
if (n==1) {
_thread2.text =@"线程2启动";
_thread2.backgroundColor = [UIColorredColor];
}
if (n==2) {
_thread3.text =@"线程3启动";
_thread3.backgroundColor = [UIColorredColor];
}
});
}
if (i==499999999) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1结束";
_thread1.backgroundColor = [UIColorcyanColor];
}
if (n==1) {
_thread2.text =@"线程2结束";
_thread2.backgroundColor = [UIColorcyanColor];
}
if (n==2) {
_thread3.text =@"线程3结束";
_thread3.backgroundColor = [UIColorcyanColor];
}
});
}
}
});
}
NSLog(@"改变背景色");
self.view.backgroundColor = [UIColoryellowColor];
并行同步:
// 创建一个并行队列
//其中第一个参数是标识符。第二个参数传DISPATCH_QUEUE_SERIAL或 NULL表示创建串行队列,传入
DISPATCH_QUEUE_CONCURRENT表示创建并行队列。
dispatch_queue_t myQueue =dispatch_queue_create("myQueue",DISPATCH_QUEUE_CONCURRENT);
//通过一个for循环将10个很耗时的异步任务加到并行队列
for (NSInteger n =0; n <3; n++) {
dispatch_async(myQueue, ^{
//模拟一个很耗时的操作
for (NSInteger i =0; i <500000000; i++) {
if (i ==
0) {
NSLog(@"并行异步任务%ld ->开始%@",n,[NSThreadcurrentThread]);
}
if (i ==
499999999) {
NSLog(@"并行异步任务%ld ->完成",(long)n);
}
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1启动";
_thread1.backgroundColor = [UIColorredColor];
}
if (n==1) {
_thread2.text =@"线程2启动";
_thread2.backgroundColor = [UIColorredColor];
}
if (n==2) {
_thread3.text =@"线程3启动";
_thread3.backgroundColor = [UIColorredColor];
}
});
}
if (i==499999999) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1结束";
_thread1.backgroundColor = [UIColorcyanColor];
}
if (n==1) {
_thread2.text =@"线程2结束";
_thread2.backgroundColor = [UIColorcyanColor];
}
if (n==2) {
_thread3.text =@"线程3结束";
_thread3.backgroundColor = [UIColorcyanColor];
}
});
}
}
});
}
self.view.backgroundColor = [UIColoryellowColor];
NSLog(@"阻塞我没有?当前线程%@",[NSThreadcurrentThread]);
并行异步:
//创建一个并行队列
dispatch_queue_t myqueue =dispatch_queue_create("myqueue",DISPATCH_QUEUE_CONCURRENT);
//创建3个耗时同步任务到并行队列
for (int n=0; n<3; n++) {
dispatch_sync(myqueue, ^{
//模拟一个很耗时的操作
for (NSInteger i =0; i <500000000; i++) {
if (i ==
0) {
NSLog(@"并行同步任务%ld ->开始%@",(long)n,[NSThreadcurrentThread]);
}
if (i ==
499999999) {
NSLog(@"并行同步任务%ld ->完成",(long)n);
}
if (i ==
0) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1启动";
_thread1.backgroundColor = [UIColorredColor];
}
if (n==1) {
_thread2.text =@"线程2启动";
_thread2.backgroundColor = [UIColorredColor];
}
if (n==2) {
_thread3.text =@"线程3启动";
_thread3.backgroundColor = [UIColorredColor];
}
});
}
if (i ==
499999999) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1结束";
_thread1.backgroundColor = [UIColorcyanColor];
}
if (n==1) {
_thread2.text =@"线程2结束";
_thread2.backgroundColor = [UIColorcyanColor];
}
if (n==2) {
_thread3.text =@"线程3结束";
_thread3.backgroundColor = [UIColorcyanColor];
}
});
}
}
});
}
self.view.backgroundColor = [UIColorpurpleColor];
线程组:
_globalQueue.backgroundColor = [UIColorcyanColor];
_globalQueue.text =@"全局队列";
_myQueue.backgroundColor = [UIColorcyanColor];
_myQueue.text =@"自定义队列";
_mainQueue.backgroundColor = [UIColorcyanColor];
_myQueue.text =@"主队列";
//创建一个线程组
dispatch_group_t group =dispatch_group_create();
//创建三个不同的并行队列
dispatch_queue_t globalQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);//只有一个全局队列
dispatch_queue_t myqueue =dispatch_queue_create("myQueue",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t mainQueue =dispatch_get_main_queue();//只有一个全局队列
//执行全局队列
dispatch_group_async(group, globalQueue, ^{
for (int i=0; i<500000; i++) {
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
_globalQueue.text =@"全局队列启动";
_globalQueue.backgroundColor = [UIColorredColor];
});
}
if (i==499999) {
dispatch_async(dispatch_get_main_queue(), ^{
_globalQueue.text =@"全局队列结束";
_globalQueue.backgroundColor = [UIColorblueColor];
[NSThread
sleepForTimeInterval:2];
});
}
}
});
//执行自定义队列
dispatch_group_async(group, myqueue, ^{
for (int i=0; i<500000; i++) {
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
_myQueue.text =@"自定义启动";
_myQueue.backgroundColor = [UIColorredColor];
});
}
if (i==499999) {
dispatch_async(dispatch_get_main_queue(), ^{
_myQueue.text =@"自定义结束";
_myQueue.backgroundColor = [UIColorblueColor];
[NSThread
sleepForTimeInterval:2];
});
}
}
});
//执行主队列
dispatch_group_async(group, mainQueue, ^{
for (int i=0; i<500000; i++) {
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
_mainQueue.text =@"主线程启动";
_mainQueue.backgroundColor = [UIColorredColor];
});
}
if (i==499999) {
dispatch_async(dispatch_get_main_queue(), ^{
_mainQueue.text =@"主线程结束";
_mainQueue.backgroundColor = [UIColorblueColor];
[NSThread
sleepForTimeInterval:2];
});
}
}
});
//队列组执行完会通知
dispatch_group_notify(group,dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView * alertView = [[UIAlertViewalloc]initWithTitle:@"bu~"message:@"队列执行完成"delegate:selfcancelButtonTitle:@"cancel"otherButtonTitles:@"sure",nil];
[alertView show];
});
});
self.view.backgroundColor = [UIColorpurpleColor];
OK,其它的就不再举例了,可以到了的github上下载例子:https://github.com/FCF5646448/FCFMultithreadingDemo
三种队列:
1、主队列,就是我们平时用到的UI主线程队列,可以调用dispatch_get_main_queue()来获得,是一个串行队列;
2、全局队列,进程中存在三个全局队列,按优先级分为:高、中(默认)、低。可以通过dispatch_get_global_queue函数传入优先级来访问队列。
3、自定义队列,就是用户自己创建的队列,通过dispatch_queue_create创建。可以通过设置属性来确定创建串行队列还是并行队列。
而我们正常敲代码的时候,也就那么几种类型:
1、串行队列,同步执行:串行队列意味着顺序执行,同步意味着不开新的线程;
2、串行队列,异步执行:串行队列意味着顺序执行,异步意味着要开新的线程;
3、并行队列,异步执行:并行队列意味着执行顺序不确定,异步执行意味着会开启线程,并行队列允许不按顺序执行
4、并行队列,同步执行:同步意味着不开线程,则还是顺序执行。
5、死锁:程序卡死。
使用多线程最应该注意的问题就是死锁了,发生死锁的最频繁的例子就是
1、主队列同步执行:
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"同步操作的线程 - %@", [NSThread currentThread]);
});
2、串行队列异步执行时,子线程用串行同步:
dispatch_queue_t myQueue = dispatch_queue_create("myQueue", NULL);
NSLog(@"之前线程 - %@", [NSThread currentThread]);
dispatch_async(myQueue, ^{
NSLog(@"同步操作之前线程 - %@", [NSThread currentThread]);
dispatch_sync(myQueue, ^{
NSLog(@"同步操作时线程 - %@", [NSThread currentThread]);
});
NSLog(@"同步操作之后线程 - %@", [NSThread currentThread]);
});
ok,下面直接上干货:
串行异步:
//创建一个串行队列
//其中第一个参数是标识符。第二个参数传DISPATCH_QUEUE_SERIAL或 NULL表示创建串行队列,传入
DISPATCH_QUEUE_CONCURRENT表示创建并行队列。
dispatch_queue_t myqueue =dispatch_queue_create("myqueue",NULL);
//通过一个for循环将3个很耗时的异步任务加到串行队列
for (int n=0; n<3; n++) {
dispatch_async(myqueue, ^{
for (int i=0; i<500000000; i++) {
if (i ==
0) {
NSLog(@"串行异步任务%ld ->开始%@",n,[NSThreadcurrentThread]);
}
if (i ==
499999999) {
NSLog(@"串行异步任务%ld ->完成",(long)n);
}
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1启动";
_thread1.backgroundColor = [UIColorredColor];
}
if (n==1) {
_thread2.text =@"线程2启动";
_thread2.backgroundColor = [UIColorredColor];
}
if (n==2) {
_thread3.text =@"线程3启动";
_thread3.backgroundColor = [UIColorredColor];
}
});
}
if (i==499999999) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1结束";
_thread1.backgroundColor = [UIColorcyanColor];
}
if (n==1) {
_thread2.text =@"线程2结束";
_thread2.backgroundColor = [UIColorcyanColor];
}
if (n==2) {
_thread3.text =@"线程3结束";
_thread3.backgroundColor = [UIColorcyanColor];
}
});
}
}
});
}
//
self.view.backgroundColor = [UIColoryellowColor];
串行同步:
// 创建一个串行队列
//其中第一个参数是标识符。第二个参数传DISPATCH_QUEUE_SERIAL或 NULL表示创建串行队列,传入
DISPATCH_QUEUE_CONCURRENT表示创建并行队列。
dispatch_queue_t myQueue =dispatch_queue_create("myQueue",NULL);
//通过一个for循环将3个很耗时的同步任务加到串行队列
for (NSInteger n =0; n <3; n++) {
dispatch_sync(myQueue, ^{
for (int i=0; i<500000000; i++) {
if (i ==
0) {
NSLog(@"串行同步任务%ld ->开始%@",n,[NSThreadcurrentThread]);
}
if (i ==
499999999) {
NSLog(@"串行同步任务%ld ->完成",(long)n);
}
//界面一定要主线程刷新,所以UI都是在这三个线程都执行完后统一刷新的
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1启动";
_thread1.backgroundColor = [UIColorredColor];
}
if (n==1) {
_thread2.text =@"线程2启动";
_thread2.backgroundColor = [UIColorredColor];
}
if (n==2) {
_thread3.text =@"线程3启动";
_thread3.backgroundColor = [UIColorredColor];
}
});
}
if (i==499999999) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1结束";
_thread1.backgroundColor = [UIColorcyanColor];
}
if (n==1) {
_thread2.text =@"线程2结束";
_thread2.backgroundColor = [UIColorcyanColor];
}
if (n==2) {
_thread3.text =@"线程3结束";
_thread3.backgroundColor = [UIColorcyanColor];
}
});
}
}
});
}
NSLog(@"改变背景色");
self.view.backgroundColor = [UIColoryellowColor];
并行同步:
// 创建一个并行队列
//其中第一个参数是标识符。第二个参数传DISPATCH_QUEUE_SERIAL或 NULL表示创建串行队列,传入
DISPATCH_QUEUE_CONCURRENT表示创建并行队列。
dispatch_queue_t myQueue =dispatch_queue_create("myQueue",DISPATCH_QUEUE_CONCURRENT);
//通过一个for循环将10个很耗时的异步任务加到并行队列
for (NSInteger n =0; n <3; n++) {
dispatch_async(myQueue, ^{
//模拟一个很耗时的操作
for (NSInteger i =0; i <500000000; i++) {
if (i ==
0) {
NSLog(@"并行异步任务%ld ->开始%@",n,[NSThreadcurrentThread]);
}
if (i ==
499999999) {
NSLog(@"并行异步任务%ld ->完成",(long)n);
}
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1启动";
_thread1.backgroundColor = [UIColorredColor];
}
if (n==1) {
_thread2.text =@"线程2启动";
_thread2.backgroundColor = [UIColorredColor];
}
if (n==2) {
_thread3.text =@"线程3启动";
_thread3.backgroundColor = [UIColorredColor];
}
});
}
if (i==499999999) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1结束";
_thread1.backgroundColor = [UIColorcyanColor];
}
if (n==1) {
_thread2.text =@"线程2结束";
_thread2.backgroundColor = [UIColorcyanColor];
}
if (n==2) {
_thread3.text =@"线程3结束";
_thread3.backgroundColor = [UIColorcyanColor];
}
});
}
}
});
}
self.view.backgroundColor = [UIColoryellowColor];
NSLog(@"阻塞我没有?当前线程%@",[NSThreadcurrentThread]);
并行异步:
//创建一个并行队列
dispatch_queue_t myqueue =dispatch_queue_create("myqueue",DISPATCH_QUEUE_CONCURRENT);
//创建3个耗时同步任务到并行队列
for (int n=0; n<3; n++) {
dispatch_sync(myqueue, ^{
//模拟一个很耗时的操作
for (NSInteger i =0; i <500000000; i++) {
if (i ==
0) {
NSLog(@"并行同步任务%ld ->开始%@",(long)n,[NSThreadcurrentThread]);
}
if (i ==
499999999) {
NSLog(@"并行同步任务%ld ->完成",(long)n);
}
if (i ==
0) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1启动";
_thread1.backgroundColor = [UIColorredColor];
}
if (n==1) {
_thread2.text =@"线程2启动";
_thread2.backgroundColor = [UIColorredColor];
}
if (n==2) {
_thread3.text =@"线程3启动";
_thread3.backgroundColor = [UIColorredColor];
}
});
}
if (i ==
499999999) {
dispatch_async(dispatch_get_main_queue(), ^{
if (n==0) {
_thread1.text =@"线程1结束";
_thread1.backgroundColor = [UIColorcyanColor];
}
if (n==1) {
_thread2.text =@"线程2结束";
_thread2.backgroundColor = [UIColorcyanColor];
}
if (n==2) {
_thread3.text =@"线程3结束";
_thread3.backgroundColor = [UIColorcyanColor];
}
});
}
}
});
}
self.view.backgroundColor = [UIColorpurpleColor];
线程组:
_globalQueue.backgroundColor = [UIColorcyanColor];
_globalQueue.text =@"全局队列";
_myQueue.backgroundColor = [UIColorcyanColor];
_myQueue.text =@"自定义队列";
_mainQueue.backgroundColor = [UIColorcyanColor];
_myQueue.text =@"主队列";
//创建一个线程组
dispatch_group_t group =dispatch_group_create();
//创建三个不同的并行队列
dispatch_queue_t globalQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);//只有一个全局队列
dispatch_queue_t myqueue =dispatch_queue_create("myQueue",DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t mainQueue =dispatch_get_main_queue();//只有一个全局队列
//执行全局队列
dispatch_group_async(group, globalQueue, ^{
for (int i=0; i<500000; i++) {
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
_globalQueue.text =@"全局队列启动";
_globalQueue.backgroundColor = [UIColorredColor];
});
}
if (i==499999) {
dispatch_async(dispatch_get_main_queue(), ^{
_globalQueue.text =@"全局队列结束";
_globalQueue.backgroundColor = [UIColorblueColor];
[NSThread
sleepForTimeInterval:2];
});
}
}
});
//执行自定义队列
dispatch_group_async(group, myqueue, ^{
for (int i=0; i<500000; i++) {
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
_myQueue.text =@"自定义启动";
_myQueue.backgroundColor = [UIColorredColor];
});
}
if (i==499999) {
dispatch_async(dispatch_get_main_queue(), ^{
_myQueue.text =@"自定义结束";
_myQueue.backgroundColor = [UIColorblueColor];
[NSThread
sleepForTimeInterval:2];
});
}
}
});
//执行主队列
dispatch_group_async(group, mainQueue, ^{
for (int i=0; i<500000; i++) {
if (i==0) {
dispatch_async(dispatch_get_main_queue(), ^{
_mainQueue.text =@"主线程启动";
_mainQueue.backgroundColor = [UIColorredColor];
});
}
if (i==499999) {
dispatch_async(dispatch_get_main_queue(), ^{
_mainQueue.text =@"主线程结束";
_mainQueue.backgroundColor = [UIColorblueColor];
[NSThread
sleepForTimeInterval:2];
});
}
}
});
//队列组执行完会通知
dispatch_group_notify(group,dispatch_get_main_queue(), ^{
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView * alertView = [[UIAlertViewalloc]initWithTitle:@"bu~"message:@"队列执行完成"delegate:selfcancelButtonTitle:@"cancel"otherButtonTitles:@"sure",nil];
[alertView show];
});
});
self.view.backgroundColor = [UIColorpurpleColor];
OK,其它的就不再举例了,可以到了的github上下载例子:https://github.com/FCF5646448/FCFMultithreadingDemo
相关文章推荐
- Python3写爬虫(四)多线程实现数据爬取
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- C#实现多线程的同步方法实例分析
- 浅谈chuck-lua中的多线程
- C#简单多线程同步和优先权用法实例
- C#多线程学习之(四)使用线程池进行多线程的自动管理
- C#多线程编程中的锁系统(三)
- 解析C#多线程编程中异步多线程的实现及线程池的使用
- C#多线程学习之(六)互斥对象用法实例
- 基于一个应用程序多线程误用的分析详解
- C#多线程学习之(三)生产者和消费者用法分析
- C#多线程学习之(一)多线程的相关概念分析
- C#多线程之Thread中Thread.IsAlive属性用法分析
- 分享我在工作中遇到的多线程下导致RCW无法释放的问题