iOS多線程小結(jié)

同步異步串行并行

  • 同步串行:不開啟線程
  • 同步并行:不開啟線程
  • 異步串行:最多開啟一個線程
  • 異步并行:開啟線程
  • 同步:不開啟線程喧务,并將添加信號鎖篙螟。同步會阻塞當前線程
  • 異步:可以開啟線程
  • 串行:任務(wù)一個一個執(zhí)行
  • 并行:任務(wù)不用一個一個執(zhí)行

線程死鎖

在一個線程中一個串行隊列中兩個同步任務(wù)相互等待出現(xiàn)線程死鎖

- (void)test1{
    dispatch_queue_t queueSerial = dispatch_queue_create("queueSerial", DISPATCH_QUEUE_SERIAL);
    /** 同步隊列中兩個任務(wù)相互等待 */
        dispatch_sync(queueSerial, ^{
            dispatch_sync(queueSerial, ^{
            });
        });
}
- (void)test2{
    /** 主隊列中兩個任務(wù)相互等待 */
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"22");
        });
}
- (void)test3{
    /** 兩個隊列中任務(wù)相互等待 */
    dispatch_queue_t queueSerialOne = dispatch_queue_create("queueSerial", DISPATCH_QUEUE_SERIAL);
    dispatch_queue_t queueSerialTwo = dispatch_queue_create("queueSerial", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queueSerialOne, ^{
        dispatch_sync(queueSerialTwo, ^{
            dispatch_sync(queueSerialOne, ^{
                
            });
        });
    });
}

死鎖解釋:同步開啟信號量题山,信號量的++被壓到了最下面

 dispatch_async(queue, ^{
 dispatch_semaphore_signal(semaphore);
 });

延遲執(zhí)行

默認方式是異步御板,使用主要隊列會在主線程中執(zhí)行
使用串行隊列會開啟線程

- (void)test4{
    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC));
    dispatch_queue_t queueSerialOne = dispatch_queue_create("queueSerial", DISPATCH_QUEUE_SERIAL);
    dispatch_after(time, queueSerialOne, ^{
    });
}

dispatch_group_t: 可以阻塞當前線程特咆,當所有任務(wù)完成時在往下執(zhí)行
dispatch_group_notify: 可以不阻塞當前線程

- (void)test5{
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_async(group, queue, ^{
    });
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
}

- (void)test6{
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_async(group, queue, ^{
    });
    dispatch_group_notify(group, queue, ^{
    });
}

多次執(zhí)行

dispatch_apply: 會阻塞當前線程

- (void)test7{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_apply(10, queue, ^(size_t i) {
    });
}

隊列特有數(shù)據(jù)

- (void)test8{
    dispatch_queue_t queueA = dispatch_queue_create("queueA", NULL);
    dispatch_queue_t queueB = dispatch_queue_create("queueB", NULL);
    dispatch_set_target_queue(queueB, queueA);
    
    static int kQeueueSpecific;
    CFStringRef queueSpecificValue = CFSTR("queueA");
    dispatch_queue_set_specific(queueA, &kQeueueSpecific, (void *)queueSpecificValue, (dispatch_function_t)CFRelease);
    dispatch_sync(queueB, ^{
        dispatch_block_t block = ^{
            NSLog(@"2222");
        };
        CFStringRef retrievedValue = dispatch_get_specific(&kQeueueSpecific);
        if (retrievedValue) {
            block();
        }else{
            dispatch_sync(queueA, block);
        }
    });
}

規(guī)律小結(jié)

  • 串行隊列中通過異步開啟線程患民,最多只能開啟一個
  • 串行隊列的末尾有信號量,需要等待執(zhí)行完成后衣赶,才能往下一個執(zhí)行
  • 在一個線程中一個串行隊列中兩個同步任務(wù)相互等待出現(xiàn)線程死鎖诊赊,信號量的++被壓到了最下面
  • 異步?jīng)Q定是否開啟線程,并且是否開啟信號量
  • 串行隊列按照順序執(zhí)行
  • 同步下任務(wù)相互等待會造成線程死鎖

NSOpetation

- (void)opration{
    //    在當前線程使用子類 NSInvocationOperation
    [self useInvocationOperation];
    
    //    在其他線程使用子類 NSInvocationOperation
    //    [NSThread detachNewThreadSelector:@selector(useInvocationOperation) toTarget:self withObject:nil];
    
    //    在當前線程使用 NSBlockOperation
    //    [self useBlockOperation];
    
    //    使用 NSBlockOperation 的 AddExecutionBlock: 方法
    //    [self useBlockOperationAddExecutionBlock];
    
    //    使用自定義繼承自 NSOperation 的子類
    //    [self useCustomOperation];
    
    //    使用addOperation: 添加操作到隊列中
    //    [self addOperationToQueue];
    
    //    使用 addOperationWithBlock: 添加操作到隊列中
    //    [self addOperationWithBlockToQueue];
    
    //    設(shè)置最大并發(fā)操作數(shù)(MaxConcurrentOperationCount)
    //    [self setMaxConcurrentOperationCount];
    
    //    設(shè)置優(yōu)先級
    //    [self setQueuePriority];
    //    添加依賴
    //    [self addDependency];
    
    //    線程間的通信
    //    [self communication];
    
    //    完成操作
    //    [self completionBlock];
    
    //    不考慮線程安全
    //    [self initTicketStatusNotSave];
    
    //    考慮線程安全
    //    [self initTicketStatusSave];
}

使用子類 NSInvocationOperation

- (void)useInvocationOperation {
    
    // 1.創(chuàng)建 NSInvocationOperation 對象
    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task1) object:nil];
    
    // 2.調(diào)用 start 方法開始執(zhí)行操作
    [op start];
}

使用子類 NSBlockOperation

- (void)useBlockOperation {
   
   // 1.創(chuàng)建 NSBlockOperation 對象
   NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
       for (int i = 0; i < 2; i++) {
           [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
           NSLog(@"1---%@", [NSThread currentThread]); // 打印當前線程
       }
   }];
   
   // 2.調(diào)用 start 方法開始執(zhí)行操作
   [op start];
}

使用子類 NSBlockOperation

  • 使用子類 NSBlockOperation
  • 調(diào)用方法 AddExecutionBlock:
- (void)useBlockOperationAddExecutionBlock {
    
    // 1.創(chuàng)建 NSBlockOperation 對象
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"1---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    
    // 2.添加額外的操作
    [op addExecutionBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"2---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    [op addExecutionBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"3---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    [op addExecutionBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"4---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    [op addExecutionBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"5---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    [op addExecutionBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"6---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    [op addExecutionBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"7---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    [op addExecutionBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"8---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    
    // 3.調(diào)用 start 方法開始執(zhí)行操作
    [op start];
}

使用自定義繼承自 NSOperation 的子類

- (void)useCustomOperation {
    // 1.創(chuàng)建 YSCOperation 對象
    YSCOperation *op = [[YSCOperation alloc] init];
    // 2.調(diào)用 start 方法開始執(zhí)行操作
    [op start];
}

使用 addOperation: 將操作加入到操作隊列中

- (void)addOperationToQueue {
    // 1.創(chuàng)建隊列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 2.創(chuàng)建操作
    // 使用 NSInvocationOperation 創(chuàng)建操作1
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task1) object:nil];
    
    // 使用 NSInvocationOperation 創(chuàng)建操作2
    NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task2) object:nil];
    
    // 使用 NSBlockOperation 創(chuàng)建操作3
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"3---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    
    [op3 addExecutionBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"4---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    
    // 3.使用 addOperation: 添加所有操作到隊列中
    [queue addOperation:op1]; // [op1 start]
    [queue addOperation:op2]; // [op2 start]
    [queue addOperation:op3]; // [op3 start]
}

使用 addOperationWithBlock: 將操作加入到操作隊列中

- (void)addOperationWithBlockToQueue {
    // 1.創(chuàng)建隊列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 2.使用 addOperationWithBlock: 添加操作到隊列中
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"1---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"2---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"3---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
}

設(shè)置 MaxConcurrentOperationCount(最大并發(fā)操作數(shù))

- (void)setMaxConcurrentOperationCount {
    // 1.創(chuàng)建隊列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 2.設(shè)置最大并發(fā)操作數(shù)
    queue.maxConcurrentOperationCount = 1; // 串行隊列
    //    queue.maxConcurrentOperationCount = 2; // 并發(fā)隊列
    //    queue.maxConcurrentOperationCount = 8; // 并發(fā)隊列
    
    // 3.添加操作
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"1---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"2---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"3---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    [queue addOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"4---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
}

設(shè)置優(yōu)先級

  • 就緒狀態(tài)下府瞄,優(yōu)先級高的會優(yōu)先執(zhí)行碧磅,但是執(zhí)行時間長短并不是一定的,所以優(yōu)先級高的并不是一定會先執(zhí)行完畢
- (void)setQueuePriority
{
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        
        for (int i = 0; i < 2; i++) {
            NSLog(@"1-----%@", [NSThread currentThread]);
            [NSThread sleepForTimeInterval:2];
        }
    }];
    [op1 setQueuePriority:(NSOperationQueuePriorityVeryLow)];
    
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        
        for (int i = 0; i < 2; i++) {
            NSLog(@"2-----%@", [NSThread currentThread]);
            [NSThread sleepForTimeInterval:2];
        }
    }];
    
    [op2 setQueuePriority:(NSOperationQueuePriorityVeryHigh)];
    
    [queue addOperation:op1];
    [queue addOperation:op2];
}

操作依賴

  • 使用方法:addDependency:
- (void)addDependency {
   // 1.創(chuàng)建隊列
   NSOperationQueue *queue = [[NSOperationQueue alloc] init];
   
   // 2.創(chuàng)建操作
   NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
       for (int i = 0; i < 2; i++) {
           [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
           NSLog(@"1---%@", [NSThread currentThread]); // 打印當前線程
       }
   }];
   NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
       for (int i = 0; i < 2; i++) {
           [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
           NSLog(@"2---%@", [NSThread currentThread]); // 打印當前線程
       }
   }];
   
   // 3.添加依賴
   [op2 addDependency:op1];    // 讓op2 依賴于 op1遵馆,則先執(zhí)行op1鲸郊,在執(zhí)行op2
   
   // 4.添加操作到隊列中
   [queue addOperation:op1];
   [queue addOperation:op2];
}

線程間通信

- (void)communication {
   // 1.創(chuàng)建隊列
   NSOperationQueue *queue = [[NSOperationQueue alloc]init];
   
   // 2.添加操作
   [queue addOperationWithBlock:^{
       // 異步進行耗時操作
       for (int i = 0; i < 2; i++) {
           [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
           NSLog(@"1---%@", [NSThread currentThread]); // 打印當前線程
       }
       
       // 回到主線程
       [[NSOperationQueue mainQueue] addOperationWithBlock:^{
           // 進行一些 UI 刷新等操作
           for (int i = 0; i < 2; i++) {
               [NSThread sleepForTimeInterval:2];      // 模擬耗時操作
               NSLog(@"2---%@", [NSThread currentThread]); // 打印當前線程
           }
       }];
   }];
}

完成操作 completionBlock

- (void)completionBlock {
    // 1.創(chuàng)建隊列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 2.創(chuàng)建操作
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"1---%@", [NSThread currentThread]); // 打印當前線程
        }
    }];
    
    // 3.添加完成操作
    op1.completionBlock = ^{
        for (int i = 0; i < 2; i++) {
            [NSThread sleepForTimeInterval:2];          // 模擬耗時操作
            NSLog(@"2---%@", [NSThread currentThread]); // 打印當前線程
        }
    };
    
    // 4.添加操作到隊列中
    [queue addOperation:op1];
}

線程安全

  • 非線程安全:不使用 NSLock
  • 初始化火車票數(shù)量、賣票窗口(非線程安全)团搞、并開始賣票
- (void)initTicketStatusNotSave {
   NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印當前線程
   
   self.ticketSurplusCount = 50;
   
   // 1.創(chuàng)建 queue1,queue1 代表北京火車票售賣窗口
   NSOperationQueue *queue1 = [[NSOperationQueue alloc] init];
   queue1.maxConcurrentOperationCount = 1;
   
   // 2.創(chuàng)建 queue2,queue2 代表上貉贤火車票售賣窗口
   NSOperationQueue *queue2 = [[NSOperationQueue alloc] init];
   queue2.maxConcurrentOperationCount = 1;
   
   
   // 3.創(chuàng)建賣票操作 op1
   __weak typeof(self) weakSelf = self;
   NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
       [weakSelf saleTicketNotSafe];
   }];
   
   // 4.創(chuàng)建賣票操作 op2
   NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
       [weakSelf saleTicketNotSafe];
   }];
   
   // 5.添加操作,開始賣票
   [queue1 addOperation:op1];
   [queue2 addOperation:op2];
}

售賣火車票(非線程安全)

- (void)saleTicketNotSafe {
   while (1) {
       
       if (self.ticketSurplusCount > 0) {
           
           //如果還有票逻恐,繼續(xù)售賣
           self.ticketSurplusCount--;
           NSLog(@"%@", [NSString stringWithFormat:@"剩余票數(shù):%d 窗口:%@", self.ticketSurplusCount, [NSThread currentThread]]);
           [NSThread sleepForTimeInterval:0.2];
       } else {
           NSLog(@"所有火車票均已售完");
           break;
       }
   }
}

線程安全:使用 NSLock 加鎖

  • 初始化火車票數(shù)量像吻、賣票窗口(線程安全)、并開始賣票
- (void)initTicketStatusSave {
   NSLog(@"currentThread---%@",[NSThread currentThread]);  // 打印當前線程
   
   self.ticketSurplusCount = 50;
   
   self.lock = [[NSLock alloc] init];
   // 1.創(chuàng)建 queue1,queue1 代表北京火車票售賣窗口
   NSOperationQueue *queue1 = [[NSOperationQueue alloc] init];
   queue1.maxConcurrentOperationCount = 1;
   
   // 2.創(chuàng)建 queue2,queue2 代表上焊绰。火車票售賣窗口
   NSOperationQueue *queue2 = [[NSOperationQueue alloc] init];
   queue2.maxConcurrentOperationCount = 1;
   
   // 3.創(chuàng)建賣票操作 op1
   __weak typeof(self) weakSelf = self;
   NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
       [weakSelf saleTicketSafe];
   }];
   
   // 4.創(chuàng)建賣票操作 op2
   NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
       [weakSelf saleTicketSafe];
   }];
   
   // 5.添加操作拨匆,開始賣票
   [queue1 addOperation:op1];
   [queue2 addOperation:op2];
}

售賣火車票(線程安全)

- (void)saleTicketSafe {
    while (1) {
        // 加鎖
        [self.lock lock];
        
        if (self.ticketSurplusCount > 0) {
            //如果還有票,繼續(xù)售賣
            self.ticketSurplusCount--;
            NSLog(@"%@", [NSString stringWithFormat:@"剩余票數(shù):%d 窗口:%@", self.ticketSurplusCount, [NSThread currentThread]]);
            [NSThread sleepForTimeInterval:0.2];
        }
        // 解鎖
        [self.lock unlock];
        
        if (self.ticketSurplusCount <= 0) {
            NSLog(@"所有火車票均已售完");
            break;
        }
    }
}
/**
 * 任務(wù)1
 */
- (void)task1 {
    for (int i = 0; i < 2; i++) {
        [NSThread sleepForTimeInterval:2];              // 模擬耗時操作
        NSLog(@"1---%@", [NSThread currentThread]);     // 打印當前線程
    }
}

/**
 * 任務(wù)2
 */
- (void)task2 {
    for (int i = 0; i < 2; i++) {
        [NSThread sleepForTimeInterval:2];              // 模擬耗時操作
        NSLog(@"2---%@", [NSThread currentThread]);     // 打印當前線程
    }
}

下載

參考:

http://www.cocoachina.com/ios/20170801/20089.html
http://www.reibang.com/p/5e6300cb3fc5
http://www.reibang.com/p/93c1012c2e48
http://www.reibang.com/p/4b1d77054b35

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末挽拂,一起剝皮案震驚了整個濱河市惭每,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌亏栈,老刑警劉巖台腥,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異绒北,居然都是意外死亡黎侈,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門闷游,熙熙樓的掌柜王于貴愁眉苦臉地迎上來峻汉,“玉大人贴汪,你說我怎么就攤上這事⌒莘停” “怎么了扳埂?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長瘤礁。 經(jīng)常有香客問我阳懂,道長,這世上最難降的妖魔是什么蔚携? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任希太,我火速辦了婚禮茬末,結(jié)果婚禮上肺素,老公的妹妹穿的比我還像新娘弦悉。我一直安慰自己,他們只是感情好亡脑,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著邀跃,像睡著了一般霉咨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上拍屑,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天途戒,我揣著相機與錄音,去河邊找鬼僵驰。 笑死喷斋,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的蒜茴。 我是一名探鬼主播星爪,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼粉私!你這毒婦竟也來了顽腾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤诺核,失蹤者是張志新(化名)和其女友劉穎抄肖,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窖杀,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡漓摩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了陈瘦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幌甘。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡潮售,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出锅风,到底是詐尸還是另有隱情酥诽,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布皱埠,位于F島的核電站肮帐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏边器。R本人自食惡果不足惜训枢,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望忘巧。 院中可真熱鬧恒界,春花似錦、人聲如沸砚嘴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽际长。三九已至耸采,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間工育,已是汗流浹背虾宇。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留如绸,地道東北人嘱朽。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像竭沫,于是被迫代替她去往敵國和親燥翅。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361

推薦閱讀更多精彩內(nèi)容

  • NSThread 第一種:通過NSThread的對象方法 NSThread *thread = [[NSThrea...
    攻城獅GG閱讀 805評論 0 3
  • 在這篇文章中蜕提,我將為你整理一下 iOS 開發(fā)中幾種多線程方案森书,以及其使用方法和注意事項。當然也會給出幾種多線程的案...
    張戰(zhàn)威ican閱讀 603評論 0 0
  • 首先明確線程和進程的關(guān)系和區(qū)別: 一個程序至少有一個進程,一個進程至少有一個線程. 線程的劃分尺度小于進程谎势,使得多...
    kkj1996閱讀 208評論 0 0
  • 在網(wǎng)上看到兩個視頻脏榆,感覺像吞了一只蒼蠅一樣難受猖毫。 一個視頻講述的事情發(fā)生在美國,當工作人員喬裝成一個形跡可疑的男子...
    危笑天閱讀 1,231評論 5 2
  • 我姑且把當下當作是春天须喂。 在這個春意盎然吁断,春寒料峭趁蕊,卻鮮花盛開的日子里,每一寸土地都透著滿滿的詩意仔役。 春天因為萬物...
    平果綠閱讀 371評論 0 0