多线程的简单了解

1、程序、进程、线程

程序:程序是存放在磁盘上的一系列代码和数据

进程:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的一个独立单位。每个程序启动后都会有一个进程

线程:它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程。但线程不能单独执行,必须组成进程,一个进程至少有一个主线程

主线程:当我们应用程序刚刚运行的时候,系统会自动为我们开放一个线程,这个线程叫做主线程

自线程:程序员用代码手动开启的线程

线程的存在意义:执行耗时操作的任务

子线程在执行完自己的任务之后会自动销毁

2、多线程的优缺点

优点:

(1)多线程技术使程序的响应速度更快 ,因为用户界面可以在进行其它工作的同时一直处于活动状态;

(2)当前没有进行处理的任务时可以将处理器时间让给其它任务;

(3)占用大量处理时间的任务可以定期将处理器时间让给其它任务;

(4)可以随时停止任务;

(5)可以分别设置各个任务的优先级以优化性能

缺点:

(1)等候使用共享资源时造成程序的运行速度变慢。这些共享资源主要是独占性的资源 ,如打印机等。

(2)对线程进行管理要求额外的 CPU开销。线程的使用会给系统带来上下文切换的额外负担。当这种负担超过一定程度时,多线程的特点主要表现在其缺点上,比如用独立的线程来更新数组内每个元素。

(3)线程的死锁。即较长时间的等待或资源竞争以及死锁等多线程症状。

(4)对公有变量的同时读或写。当多个线程需要对公有变量进行写操作时,后一个线程往往会修改掉前一个线程存放的数据,从而使前一个线程的参数被修改;另外 ,当公用变量的读写操作是非原子性时,在不同的机器上,中断时间的不确定性,会导致数据在一个线程内的操作产生错误,从而产生莫名其妙的错误,而这种错误是程序员无法预知的。(这种情况下,需要使用线程锁)

 

通常情况下,在执行一些耗时操作的时候,如果在主线程下执行,会影响后续程序的运行。此时,就需要使用自线程。

 

3、多线程的实现方式与区别

(1)NSThread

  NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(haoshicaozuo) object:@"123"];

    [thread start];

    NSLog(@"%@", thread);

    // 当前应用程序的主线程

    NSLog(@"%@", [NSThread mainThread]);

    // 当前线程

    NSLog(@"%@", [NSThread currentThread]);

    // 判断当前线程是否为主线程

    NSLog(@"%d", [NSThread isMainThread]);

    // 快捷创建 无返回值

    [NSThread detachNewThreadSelector:@selector(haoshicaozuo) toTarget:self withObject:@"456"];

    // 隐式开启线程

    [self performSelectorInBackground:@selector(haoshicaozuo) withObject:@"789"];

(2)NSOperation

// NSOperation 是一个抽象类,我们一般不使用它,而是使用它的子类NSInvocationOperation NSBlockOperation

// 如果他们单独使用,都是在主线程执行的,只有和队列放一起使用,才是在自线程下执行的

    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction1) object:nil];

    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationAction2) object:nil];

    NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{

        NSLog(@"222");

    }];

    // 操作队列

    // 目的:是将我们的任务放在一个队列中执行

    // 任务:任务执行在主线程还是自线程全都是由我们的队列来决定的

    // 加入到队列

    // mainQueue  代表着主队列

    NSOperationQueue *queue = [NSOperationQueue mainQueue];

    // 如果是alloc init   代表着其他队列

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    // 先加的先执行,后加的后执行。但是执行的时间不一定,可能后执行的比先执行的先执行完

    [queue addOperation:operation1];

    [queue addOperation:operation2];

    [queue addOperation:operation3];

(3) GCD (伟大的中枢调度器、共(和)产(谐)党)

队列分为:1、串行队列:像肉串一样,从上往下的执行顺序(主线程就是串行队列)

       2、并行队列:排成一排,同时开始执行

同步:在同一线程,从上往下依次执行

异步:在不同的线程中执行

1、同步+主队列 (改方式是错误的,同步中不能获得主队列

dispatch_queue_t queue = dispatch_get_main_queue(); // 获得主队列

    // 将任务加到队列中

  // dispatch_sync 表示同步

    // 第一个参数:放到队列中的

    // 第二个参数:要执行的任务

    dispatch_sync(queue, ^{  

        NSLog(@"1-----------%@", [NSThread currentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"2-----------%@", [NSThread currentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"3-----------%@", [NSThread currentThread]);

    });

2、异步 + 主队列 (没有意义,都是在主队列中依次往下执行)

dispatch_queue_t queue = dispatch_get_main_queue();

  // dispatch_async 表示异步

    dispatch_async(queue, ^{

        NSLog(@"111111");

    });

    dispatch_async(queue, ^{

        NSLog(@"222222");

    });

    dispatch_async(queue, ^{

        NSLog(@"333333");

    });

3、同步 + 串行 (不具备开启自线程的能力)

// DISPATCH_QUEUE_SERIAL 表示串行

dispatch_queue_t queue = dispatch_queue_create("aaaa.com.queue", DISPATCH_QUEUE_SERIAL);

    dispatch_sync(queue, ^{

        NSLog(@"1-----------%@", [NSThread currentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"2-----------%@", [NSThread currentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"3-----------%@", [NSThread currentThread]);

    });

4、异步 + 串行 (具备开启自线程的能力)

dispatch_queue_t queue = dispatch_queue_create("bbb", DISPATCH_QUEUE_SERIAL);

    dispatch_async(queue, ^{

        NSLog(@"1-----------%@", [NSThread currentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"2-----------%@", [NSThread currentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"3-----------%@", [NSThread currentThread]);

    });

5、同步 + 并发队列 (不具备开启线程的能力,并发的功能也就没用了

// 第一个参数:队列的名字

    // 第二个参数:类型

    // 自己创建的并发队列

  //    dispatch_queue_t queue = dispatch_queue_create("sb.2b", DISPATCH_QUEUE_CONCURRENT);

    // 创建并发队列

    // 获得全局的并发队列

    // 第一个参数:优先级 默认的就行

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_sync(queue, ^{

        NSLog(@"1-----------%@", [NSThread currentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"2-----------%@", [NSThread currentThread]);

    });

    dispatch_sync(queue, ^{

        NSLog(@"3-----------%@", [NSThread currentThread]);

    });

6、异步 + 并发 (具备开启线程的能力,并且并发执行任务) (改方式最为常用)

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(queue, ^{

        NSLog(@"1-----------%@", [NSThread currentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"2-----------%@", [NSThread currentThread]);

    });

    dispatch_async(queue, ^{

        NSLog(@"3-----------%@", [NSThread currentThread]);

    });

}

 

posted @ 2016-07-21 20:26  程春玉  阅读(119)  评论(0编辑  收藏  举报