文档章节

GCD

JK_Jack
 JK_Jack
发布于 2015/10/19 17:24
字数 1539
阅读 1
收藏 0
点赞 0
评论 0


一个线程就是一个任务的执行


/*
 

 
什么是进程:系统分配资源的最小单位(一个APP运行时在内存中所需要的所有资源)
 
什么是线程:cup运行的最小基本单位,一个线程就是一个任务
 
有什么区别: 1.一个进程可以包含多个线程,系统至少会为APP开辟一个进程,一个进程至少会有一个线程(主线程)
            2.
每个进程有自己独立的堆栈空间,一个进程奔溃(死掉)不会影响其他进程
            3.
线程没有自己独立的堆栈空间,统一使用进程的内存空间,一个线程死掉,整个进程都会死掉
 
多线程的实质:CPU快速的在各个线程之间切换,由于CPU的执行速度很快,我们根本感觉不到,就相当于多个任务同时执行,这也是为什么我们的电脑开得程序过多就会感觉性能下降的原因。

 */




#pragma mark 点击按钮执行的方法
- (IBAction)doButton:(id)sender {
   
//查看当前是否在主线程
//    NSLog(@"%d",[[NSThread currentThread] isMainThread]);
 
//线程阻塞(UI冻结)
   
/*
    //INTMAX_MAX
是支持的最大整形数字
    //
单一线程容易造成UI冻结
    for (NSInteger i =0; i < INTMAX_MAX; i++) {
        NSLog(@"
卡死了");
    }
    */

   
   
   
//1.开辟子线程的第一种方式*********************
   
/*
    //object:
通常使用object来完成从主线程向子线程传值的对象
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(doThread1:) object:@"123"];
    //
线程的优先级
    thread.threadPriority = 0.8;
    //
用这种方式创建的多线程需要手动开启
    [thread start];
   
    NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(doThread2:) object:nil];
    //
    thread2.threadPriority = 0.1;
    thread2.name = @"
窗口2";
    [thread2 start];
    */

   
//2.第二种方式开辟子线程的方式******************
   
//该方法不需要手动开启
    [
NSThread detachNewThreadSelector:@selector(doThread3:) toTarget:self withObject:nil];

   
//3.线程之间的互斥**************************
   
//线程互斥:因为线程没有自己独立的堆栈空间,都是使用进程的空间,所以有可能多个线程访问进程的同一块资源,这就会出现线程访问问题,多个线程访问同一个资源就叫做线程互斥,解决办法就是加线程锁
   
//加线程锁
   
   
NSLock *l =[[NSLock alloc] init];
   
   
NSThread *th1 = [[NSThread alloc] initWithTarget:self selector:@selector(doTh1:) object:l];
   
NSThread *th2 = [[NSThread alloc] initWithTarget:self selector:@selector(doTh1:) object:l];
    
NSThread *th3 = [[NSThread alloc] initWithTarget:self selector:@selector(doTh1:) object:l];
    [th1
start];
    [th2
start];
    [th3
start];
   
   
/*
    for (int i = 0; i < 100; i++) {
        NSLog(@"
主线程******");
    }
     */

   
}
/*
-(void)doThread1:(id)object
{
    //
因为在子线程中也需要做内存管理,而在MRC中用autorelease修饰的对象,需要自动释放池来释放对象,在子线程中,系统没有为我们创建自动释放池,需要我们自己手动创建一个自动释放池
    @autoreleasepool {
            //
该方法内部就是子线程
        NSLog(@"th1 =%d",[[NSThread currentThread] isMainThread]);
        NSLog(@"%@",object);
       
        for (int i = 0; i<100; i++) {
            NSLog(@"******
子线程");
        }
    }

}
 */

#pragma mark 第二个子线程执行的方法
/*
-(void)doThread2:(id)object
{
    @autoreleasepool {
        NSLog(@"%@",[[NSThread currentThread] name]);
        for (int i = 0; i < 100; i++) {
                NSLog(@"***
子线程二****");
        }
    }
}
 */

#pragma mark 第三个子线程执行的方法
-(void)doThread3:(id)object
{

       
NSURL *url = [NSURL URLWithString:BaseUrl];
       
NSURLRequest *request = [NSURLRequest requestWithURL:url];
       
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
       
UIImage *image = [UIImage imageWithData:data];
       
//不建议在Ui更新在子线程中写,因为子线程更新UI会存在潜在问题,并且耗时,费性能
       
//        self.imageView.image = image;
       
//从子线程回到主线程的方法(主要用于线程间的通信)
       
//waitUntilDone如果是YES就立刻跳转到主线程执行,执行完毕后再跳转回来接着执行下面的代码,如果NO,就行先把整个子线程的方法执行完毕后,再跳转到主线程执行
   
        [
self performSelectorOnMainThread:@selector(doMainThread:) withObject:image waitUntilDone:YES];
//            NSLog(@"11111111111111111111111111111111111111111111111");
   
/*
        for (int i = 0; i < 100; i++) {
            NSLog(@"******************************
线程三**");
        }
         */

   
}
#pragma mark -该方法是从子线程中回到主线程的方法
-(void)doMainThread:(id)object
{
   
self.imageView.image = object;
//    NSLog(@"000000000oooooooooooooooooooo=%d",[[NSThread currentThread] isMainThread]);
}

-(
void)doTh1:(id)object
{
   
NSLock *l = (NSLock *)object;

   
while (true) {
            [l
lock];
       
//假设有一百张票
       
static int num = 100;
        num--;
       
sleep(2);
       
NSLog(@"num=%d",num);
       
if (num==0) {
           
break;
        }
        [l
unlock];
    }
 
}


@end



//
//  UIImageView+CreateByUrl.m
//  Lesson22多线程下载
//
// 
// 
//

#import "UIImageView+CreateByUrl.h"

@implementation UIImageView (CreateByUrl)

-(
void)setImageByUrl:(NSString *)urlString
{
   
//block内部使用的变量
   
__block UIImageView *weakSelf = self;
   
//创建一个子线程队列来做数据请求
   
dispatch_queue_t downLoadQueue =dispatch_queue_create("downLoad", NULL);
   
//创建一个子线程
   
dispatch_async(downLoadQueue, ^{
       
NSURL *url = [NSURL URLWithString:urlString];
       
//同步
       
NSData *data = [NSData dataWithContentsOfURL:url];
       
//用请求回来的数据创建一个image
       
UIImage *image = [UIImage imageWithData:data];
       
//回到主线程
       
dispatch_sync(dispatch_get_main_queue(), ^{
          
//主线程更新UI
            weakSelf.
image = image;
        });
    });
}

@end




/  ViewController.m
//  Lesson22-多线程队列
//

//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (
void)viewDidLoad {
    [
super viewDidLoad];
   
// ***********NSObject******
   
     
//    [self performSelectorInBackground:@selector(doThread1:) withObject:@"123"];
//***********************2.NSOperationQueue********
   
//1.创建一个线程对列
   
NSOperationQueue *operation = [[NSOperationQueue alloc] init];
   
//2.在线程队列里面创建多线程
    [operation
addOperationWithBlock:^{
      
//block内部就是一个子线程
  
//        NSLog(@"block = %d",[[NSThread currentThread] isMainThread]);
       
//返回主线程
  
//        [self performSelectorOnMainThread:@selector(aaaa:) withObject:nil waitUntilDone:YES];
       
    }];
   
//*****3.NSOperationQueue
   
//1.创建队列
   
NSOperationQueue * op = [[NSOperationQueue alloc] init];
   
//创建子线程对象
   
NSInvocationOperation *inv = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doOp1:) object:nil];
    inv.
queuePriority = NSOperationQueuePriorityVeryHigh;
   
//(优先级)效果不明显
   
NSInvocationOperation *inv2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doOp2:) object:nil];
    inv2.
queuePriority = NSOperationQueuePriorityVeryLow;
   
//将子线程添加到线程队列
    [op
addOperation:inv];
    [op
addOperation:inv2];
   
//**************4.GCD(C语言)
   
/*
    //1.
创建一个队列
    //
参数一:线程队列的名字
    //
参数二:要创建线程队列的类型(串行,并行)
    dispatch_queue_t queue = dispatch_queue_create("GCD", NULL);
    //2.
在队列里面创建子线程
    //
参数一:子线程创在哪个队列里,参数二,block里面就是子线程
    dispatch_async(queue, ^{
        //
子线程
        NSLog(@"queue=%d",[[NSThread currentThread] isMainThread]);
        //
回到主线程的方法dispatch_get_main_queue()
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"sync=%d",[[NSThread currentThread] isMainThread]);
        });
    });
    */

//5.***5GCD线程队列的串行
   
/*
    //
默认是串行队列,串行队列的特点:队列里面的子线程是顺序执行的
    dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(serialQueue, ^{
        for (int i =0; i < 10; i++) {
            NSLog(@"11111");
        }
    });
    dispatch_async(serialQueue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"22222222");
        }
    });
    */

//6.*****GCD并行******
   
//DISPATCH_QUEUE_CONCURRENT表示并行队列 并行队列的特点:受队列管理的子线程是并发执行的
   
dispatch_queue_t concurrent = dispatch_queue_create("concurrent", DISPATCH_QUEUE_CONCURRENT);
   
dispatch_async(concurrent, ^{
       
for (int i = 0; i < 10; i++) {
           
NSLog(@"11111111111");
        }
    });
   
dispatch_async(concurrent, ^{
       
for (int i = 0; i < 10; i++) {
           
NSLog(@"2222");

        }

    });

   
}

/*
-(void)doThread1:(id)object
{
    NSLog(@"dothread=%d",[[NSThread currentThread] isMainThread]);
}
*/

-(
void)doOp1:(id)object
{
   
/*
    for (int i =0 ; i < 100; i++) {
        NSLog(@"op1 *******");
    }
   */

}
-(
void)doOp2:(id)object
{
   
/*
    for (int i =0 ; i < 100; i++) {
       NSLog(@" ==================op2");
    }
   
    */


}

© 著作权归作者所有

共有 人打赏支持
JK_Jack
粉丝 0
博文 6
码字总数 2658
作品 0
广州

暂无文章

idea tomcat 远程调试

tomcat 配置 编辑文件${tomcat_home}/bin/catalina.sh,在文件开头添加如下代码。    CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=7829" Idea端配......

qwfys
今天
1
0
遍历目录下的文件每250M打包一个文件

#!/usr/bin/env python # -*- utf-8 -*- # @Time : 2018/7/20 0020 下午 10:16 # @Author : 陈元 # @Email : abcmeabc@163.com # @file : tarFile.py import os import tarfile import thr......

寻爱的小草
今天
1
0
expect同步文件&expect指定host和要同步的文件&构建文件分发系统&批量远程执行命令

20.31 expect脚本同步文件 expect通过与rsync结合,可以在一台机器上把文件自动同步到多台机器上 编写脚本 [root@linux-5 ~]# cd /usr/local/sbin[root@linux-5 sbin]# vim 4.expect#!/...

影夜Linux
今天
0
0
SpringBoot | 第九章:Mybatis-plus的集成和使用

前言 本章节开始介绍数据访问方面的相关知识点。对于后端开发者而言,和数据库打交道是每天都在进行的,所以一个好用的ORM框架是很有必要的。目前,绝大部分公司都选择MyBatis框架作为底层数...

oKong
今天
12
0
win10 上安装解压版mysql

1.效果 2. 下载MySQL 压缩版 下载地址: https://downloads.mysql.com/archives/community/ 3. 配置 3.1 将下载的文件解压到合适的位置 我最终将myql文件 放在:D:\develop\mysql 最终放的位...

Lucky_Me
今天
1
0
linux服务器修改mtu值优化cpu

一、jumbo frames 相关 1、什么是jumbo frames Jumbo frames 是指比标准Ethernet Frames长的frame,即比1518/1522 bit大的frames,Jumbo frame的大小是每个设备厂商规定的,不属于IEEE标准;...

问题终结者
今天
1
0
expect脚本同步文件expect脚本指定host和要同步的文件 构建文件分发系统批量远程执行命令

expect脚本同步文件 在一台机器上把文件同步到多台机器上 自动同步文件 vim 4.expect [root@yong-01 sbin]# vim 4.expect#!/usr/bin/expectset passwd "20655739"spawn rsync -av ro...

lyy549745
今天
1
0
36.rsync下 日志 screen

10.32/10.33 rsync通过服务同步 10.34 linux系统日志 10.35 screen工具 10.32/10.33 rsync通过服务同步: rsync还可以通过服务的方式同步。那需要开启一个服务,他的架构是cs架构,客户端服务...

王鑫linux
今天
0
0
matplotlib 保存图片时的参数

简单绘图 import matplotlib.pyplot as pltplt.plot(range(10)) 保存为csv格式,放大后依然很清晰 plt.savefig('t1.svg') 普通保存放大后会有点模糊文件大小20多k plt.savefig('t5.p...

阿豪boy
今天
2
0
java 8 复合Lambda 表达式

comparator 比较器复合 //排序Comparator.comparing(Apple::getWeight);List<Apple> list = Stream.of(new Apple(1, "a"), new Apple(2, "b"), new Apple(3, "c")) .collect(......

Canaan_
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部