线程的同步、异步、串行、并行的关系

程序是由什么构成的,可能有的人会说,它是有一个个字符和逻辑共同构成的,这个说法并不完全。

程序在没有运行的状态下,是一堆代码构成的。

运行的程序是由进程程构成的,进程是程序执行的基本单位。对于进程,它可以又多个不同的线程共同构成,线程在程序中是如何运行的,他们运行的方式和关系。



    同步执行和异步执行、串行队列和并发队列的核心是:任务队列

    任务:就是执行操作,换句话说就是你在线程中执行的那段代码。

同步执行:

  •  同步执行(Sync):

       1) 同步添加任务到指定的队列中,在添加的任务执行结束之前,会一直等待,直到队列里面的任务完成之后再

        2)只能在当前线程中执行任务,不具备开启新线程的能力
  • 异步执行(Async):

        1)异步添加任务到指定的队列中,它不会做任何等待,可以继续执行任务      

         2)可以在新的线程中执行任务,具备开启新线程的能力。












同步执行和异步执行、串行队列和并发队列的核心是:任务队列

        1)同步执行和异步执行的核心: 任务

                区别: 是否等待队列的任务执行结束,以及是否具备开启新线程的能力

        串行队列和并发队列的核心: 队列

               相同: 串行队列和并发队列都符合FIFO(先进先出)的原则。

               区别: 执行的顺序不同,以及开启的线程数不同


备注:并发队列的并发功能只能在异步函数下才有效

下边使用OC中的GCD来展示以下四种组合出现的情况:

    1.同步执行 + 串行队列:

    2.异步执行 + 串行队列:

    3.同步执行 + 并发队列:

    4.异步执行 + 并发队列:


1.同步执行 + 串行队列:


//同步执行 + 串行队列
-(void)syncSerial{
    NSLog(@"CurrentThread ------%@",[NSThread currentThread]);
    NSLog(@"syncSerial------Begin");
    
    dispatch_queue_t queue = dispatch_queue_create("SerialTest", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
        // 添加任务1
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"1----------%@", [NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        // 添加任务2
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2----------%@", [NSThread currentThread]);
        }
    });
    
    dispatch_sync(queue, ^{
        // 添加任务3
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3----------%@", [NSThread currentThread]);
        }
    });
    NSLog(@"syncSerial------------end");
}

执行结果:            

2018-03-21 10:57:36.273782+0800 ThreadTest[2057:2142420] CurrentThread ------<NSThread: 0x604000078fc0>{number = 1, name = main}
2018-03-21 10:57:36.273961+0800 ThreadTest[2057:2142420] syncSerial------Begin
2018-03-21 10:57:38.274892+0800 ThreadTest[2057:2142420] 1----------<NSThread: 0x604000078fc0>{number = 1, name = main}
2018-03-21 10:57:40.275845+0800 ThreadTest[2057:2142420] 1----------<NSThread: 0x604000078fc0>{number = 1, name = main}
2018-03-21 10:57:42.277407+0800 ThreadTest[2057:2142420] 2----------<NSThread: 0x604000078fc0>{number = 1, name = main}
2018-03-21 10:57:44.278935+0800 ThreadTest[2057:2142420] 2----------<NSThread: 0x604000078fc0>{number = 1, name = main}
2018-03-21 10:57:46.279713+0800 ThreadTest[2057:2142420] 3----------<NSThread: 0x604000078fc0>{number = 1, name = main}
2018-03-21 10:57:48.281338+0800 ThreadTest[2057:2142420] 3----------<NSThread: 0x604000078fc0>{number = 1, name = main}
2018-03-21 10:57:48.281630+0800 ThreadTest[2057:2142420] syncSerial------------end

2.异步执行 + 串行队列:


// 异步并发 + 串行队列
-(void)asyncSerial{
    NSLog(@"Current Thread:-------%@",[NSThread currentThread]);
    NSLog(@"asyncSerial--------begin");
    
    dispatch_queue_t queue = dispatch_queue_create("asyncSerialTest", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        // 添加任务1
        for (int i = 0; i < 2 ; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"1--------------%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        // 添加任务2
        for (int i = 0; i < 2 ; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2--------------%@",[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        // 添加任务3
        for (int i = 0; i < 2 ; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3--------------%@",[NSThread currentThread]);
        }
    });
}

执行结果:
2018-03-21 11:01:03.131755+0800 ThreadTest[2172:2144740] Current Thread:-------<NSThread: 0x60400006f500>{number = 1, name = main}
2018-03-21 11:01:03.131923+0800 ThreadTest[2172:2144740] asyncSerial--------begin
2018-03-21 11:01:05.135621+0800 ThreadTest[2172:2144804] 1--------------<NSThread: 0x604000279bc0>{number = 3, name = (null)}
2018-03-21 11:01:07.137982+0800 ThreadTest[2172:2144804] 1--------------<NSThread: 0x604000279bc0>{number = 3, name = (null)}
2018-03-21 11:01:09.143012+0800 ThreadTest[2172:2144804] 2--------------<NSThread: 0x604000279bc0>{number = 3, name = (null)}
2018-03-21 11:01:11.146212+0800 ThreadTest[2172:2144804] 2--------------<NSThread: 0x604000279bc0>{number = 3, name = (null)}
2018-03-21 11:01:13.147072+0800 ThreadTest[2172:2144804] 3--------------<NSThread: 0x604000279bc0>{number = 3, name = (null)}
2018-03-21 11:01:15.151203+0800 ThreadTest[2172:2144804] 3--------------<NSThread: 0x604000279bc0>{number = 3, name = (null)}
3.同步执行 + 并发队列:
// 同步执行 + 并发队列
//
-(void)syncConcurrent{
    NSLog(@"currentThread-----%@",[NSThread currentThread]);
    NSLog(@"syncConcurrent----begin");
    
    // 创建一个并发队列
    dispatch_queue_t queue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_CONCURRENT);
    
    //并发队列中  添加 同步执行任务
    dispatch_sync(queue, ^{
        // 追加任务1
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:1];
            NSLog(@"1-------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        // 追加任务2
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:1];
            NSLog(@"2--------%@",[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        // 追加任务3
        for (int i = 0; i < 2; ++i) {
            [NSThread sleepForTimeInterval:1];
            NSLog(@"3---------%@", [NSThread currentThread]);
        }
    });
    NSLog(@"syncConcurrent -------- end");
}
执行结果:
2018-03-21 11:02:20.648393+0800 ThreadTest[2227:2145966] currentThread-----<NSThread: 0x600000076b80>{number = 1, name = main}
2018-03-21 11:02:20.648628+0800 ThreadTest[2227:2145966] syncConcurrent----begin
2018-03-21 11:02:21.649938+0800 ThreadTest[2227:2145966] 1-------<NSThread: 0x600000076b80>{number = 1, name = main}
2018-03-21 11:02:22.650266+0800 ThreadTest[2227:2145966] 1-------<NSThread: 0x600000076b80>{number = 1, name = main}
2018-03-21 11:02:23.650869+0800 ThreadTest[2227:2145966] 2--------<NSThread: 0x600000076b80>{number = 1, name = main}
2018-03-21 11:02:24.651351+0800 ThreadTest[2227:2145966] 2--------<NSThread: 0x600000076b80>{number = 1, name = main}
2018-03-21 11:02:25.652397+0800 ThreadTest[2227:2145966] 3---------<NSThread: 0x600000076b80>{number = 1, name = main}
2018-03-21 11:02:26.653781+0800 ThreadTest[2227:2145966] 3---------<NSThread: 0x600000076b80>{number = 1, name = main}
2018-03-21 11:02:26.654109+0800 ThreadTest[2227:2145966] syncConcurrent -------- end


4.异步执行 + 并发队列:
// 异步执行 + 并发队列
//特点:
-(void)asyncConcurrent{
    NSLog(@"asyncConcurrent ----%@ ",[NSThread currentThread]);
    NSLog(@"AsyncConcurrent----begin");
    
    // 创建并发队列
    dispatch_queue_t quenue = dispatch_queue_create("quenueTest", DISPATCH_QUEUE_CONCURRENT);
    
    // 并发队列中添加异步执行任务
    dispatch_async(quenue, ^{
        //追加任务1
        for (int i = 0; i<2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"1---------%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(quenue, ^{
        //追加任务2
        for (int i = 0; i<2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"2---------%@",[NSThread currentThread]);
        }
    });
    
    dispatch_async(quenue, ^{
        //追加任务3
        for (int i = 0; i<2; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"3---------%@",[NSThread currentThread]);
        }
    });
}
执行结果:
2018-03-21 11:03:24.971218+0800 ThreadTest[2278:2147177] asyncConcurrent ----<NSThread: 0x604000073740>{number = 1, name = main}
2018-03-21 11:03:24.971412+0800 ThreadTest[2278:2147177] AsyncConcurrent----begin
2018-03-21 11:03:26.976195+0800 ThreadTest[2278:2147265] 3---------<NSThread: 0x604000271480>{number = 4, name = (null)}
2018-03-21 11:03:26.976195+0800 ThreadTest[2278:2147267] 1---------<NSThread: 0x604000268f40>{number = 3, name = (null)}
2018-03-21 11:03:26.976225+0800 ThreadTest[2278:2147266] 2---------<NSThread: 0x604000271500>{number = 5, name = (null)}
2018-03-21 11:03:28.980970+0800 ThreadTest[2278:2147266] 2---------<NSThread: 0x604000271500>{number = 5, name = (null)}
2018-03-21 11:03:28.980980+0800 ThreadTest[2278:2147267] 1---------<NSThread: 0x604000268f40>{number = 3, name = (null)}
2018-03-21 11:03:28.980987+0800 ThreadTest[2278:2147265] 3---------<NSThread: 0x604000271480>{number = 4, name = (null)}

线程:

时间:线程在时间可以分为“串行” 和“并发”两种方式,同步就是让我们的线程同时执行,异步线程不同时执行。强调时间性。

关系:线程在线程之间关系上可以分为“顺序执行”和“并行执行”,强调的是线程之间的关系。


线程在执行的过程中,线程可以分为四种:

同步执行 + 串行队列:我们把任务分配一个个线程,每个线程的任务都在主线程中执行。

异步执行 + 串行队列:队列中的任务顺序执行:在子线程中执行,主线程继续,不会等待子线程执行完毕。

同步执行 + 并发队列:(一般不用):队列中任务顺序执行,在主线程中执行(并行)

异步执行 + 并发队列:队列中的任务同时执行;在子线程中执行;主线程继续执行,不会等待子线程执行完毕。


线程同步和异步之间的关系

同步:多个线程在同一时间同时执行。

异步:多个线程在不同时间被执行。

在多线程的执行过程中,线程之间的数据的传递、共享会存在已写小的问题,我们需要对线程进行加锁/解锁操作,对线程进行操作,达到对程序设计的目标。


每个运行中的程序都对应一个进程,每个进程可能可能由多个线程共同组成。


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值