ios-多線程(NSThread,GCD,NSOperation)

線程:

英文:Thread
線程,有時被稱為輕量級進程(Lightweight Process鳞仙,LWP)鳍烁,是程序執(zhí)行流的最小單元。一個標準的線程由線程ID繁扎,當前指令指針(PC),寄存器集合和堆棧組成糊闽。另外梳玫,線程是進程中的一個實體,是被系統(tǒng)獨立調(diào)度和分派的基本單位右犹,線程自己不擁有系統(tǒng)資源提澎,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源念链。一個線程可以創(chuàng)建和撤消另一個線程盼忌,同一進程中的多個線程之間可以并發(fā)執(zhí)行。由于線程之間的相互制約,致使線程在運行中呈現(xiàn)出間斷性首懈。線程也有就緒华畏、阻塞運行三種基本狀態(tài)。就緒狀態(tài)是指線程具備運行的所有條件跨嘉,邏輯上可以運行川慌,在等待處理機;運行狀態(tài)是指線程占有處理機正在運行祠乃;阻塞狀態(tài)是指線程在等待一個事件(如某個信號量)梦重,邏輯上不可執(zhí)行。每一個程序都至少有一個線程亮瓷,若程序只有一個線程琴拧,那就是程序本身。
線程是程序中一個單一的順序控制流程嘱支。進程內(nèi)一個相對獨立的蚓胸、可調(diào)度的執(zhí)行單元,是系統(tǒng)獨立調(diào)度和分派CPU的基本單位指運行中的程序的調(diào)度單位斗塘。在單個程序中同時運行多個線程完成不同的工作赢织,稱為多線程。 -----百度百科

ios中實現(xiàn)多線程的幾種方式:

  • Pthreads(不用)
  • NSThread(用一部分馍盟,其中幾個比較方便的方法)
  • GCD(常用)
  • NSOperation&NSOperationQueue(看需求)
- Pthreads

pthread 是 POSIX 多線程開發(fā)框架于置,是基于C 語言的跨平臺框架。沒用過贞岭,不了解八毯,感興趣的同學可以自己度娘下。

- NSThread

NSThread是基于Thread使用瞄桨,輕量級的多線程編程方法话速,一個NSThread對象代表一個線程,需要手動管理線程的生命周期芯侥,處理線程同步等問題泊交。所以一般只使用其中幾個方法,方便調(diào)試線程柱查。
[NSThread isMainThread]; // 是否主線程
[NSThread currentThread]; // 當前線程

- GCD

Apple基本c++開發(fā)的一套多線程處理技術(shù),自動管理生命周期廓俭。

任務(wù)與隊列

任務(wù):你要執(zhí)行的操作,GCD將任務(wù)放在block中唉工。執(zhí)行任務(wù)有2中方式研乒,同步執(zhí)行,異步執(zhí)行淋硝。

  • 同步
    不具備開啟線程的能力雹熬,會阻塞當前線程宽菜。
  • 異步
    具備開啟新線程的能力,不會阻塞當前線程竿报。

隊列:用來存放任務(wù)的隊列铅乡,是一種特殊的線性表,采用FIFO(先進先出)的原則仰楚,則從頂部開始讀取任務(wù)隆判,從尾部加入任務(wù)到隊列。在GCD中有3種隊列:串行隊列僧界,并行隊列侨嘀,主隊列(特殊的串行隊列)。

  • 串行隊列
    一個一個任務(wù)有序執(zhí)行捂襟,上一個任務(wù)沒執(zhí)行完畢咬腕,下一個任務(wù)不會執(zhí)行。
  • 并行隊列
    同時執(zhí)行多個任務(wù)葬荷,不用等待上一個任務(wù)執(zhí)行完畢涨共。
  • 主隊列
    和串行隊列一樣,需要等待上一個任務(wù)執(zhí)行完成宠漩,才能執(zhí)行下一個任務(wù)举反。
創(chuàng)建隊列:
  • 全局并行隊列(系統(tǒng)自帶的,全局唯一)
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  • 自定義并行隊列:
dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
  • 自定義串行隊列:
dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
  • 主隊列:
dispatch_get_main_queue()
創(chuàng)建任務(wù):
  • 同步任務(wù)
dispatch_sync(隊列, ^{要執(zhí)行的任務(wù)});
  • 異步任務(wù)
dispatch_async(隊列, ^{要執(zhí)行的任務(wù)});

基本使用:

  • 同步任務(wù)+串行隊列(不會開啟新線程扒吁,在當前線程中執(zhí)行任務(wù))
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
        NSLog(@"當前線程----->%@",[NSThread currentThread]);
 });
  • 同步任務(wù)+并行隊列(不會開啟新線程火鼻,在當前線程中執(zhí)行任務(wù))
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"當前線程----->%@",[NSThread currentThread]);
 });
  • 同步任務(wù)+主隊列(不會開啟新線程,在主線程中執(zhí)行任務(wù))
dispatch_sync(dispatch_get_main_queue(), 0), ^{
        NSLog(@"當前線程----->%@",[NSThread currentThread]);
 });
  • 異步任務(wù)+串行隊列(會開啟一條新的線程雕崩,串行執(zhí)行任務(wù))
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
        NSLog(@"當前線程----->%@",[NSThread currentThread]);
 });
  • 異步任務(wù)+并行隊列(會開啟至少一條新的線程魁索,并行執(zhí)行任務(wù))
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"當前線程----->%@",[NSThread currentThread]);
 });
  • 異步任務(wù)+主隊列(不會開啟新的線程,會在主線程中執(zhí)行任務(wù))
dispatch_async(dispatch_get_main_queue(), 0), ^{
        NSLog(@"當前線程----->%@",[NSThread currentThread]);
 });

總結(jié):
1.同步任務(wù)都不會開啟新的線程盼铁,所以會阻塞當前線程粗蔚。
2.主隊列中的任務(wù)不會開啟新的線程,會在主線程中執(zhí)行饶火。
3.異步任務(wù)+串行隊列鹏控,會開啟一條新的線程,在新的線程串行執(zhí)行任務(wù)肤寝。
4.異步任務(wù)+并行多列牧挣,會開啟至少一條新的線程,在新的線程中并發(fā)執(zhí)行任務(wù)醒陆。

線程阻塞:

實例1:

NSLog(@"當前線程----->%@",[NSThread currentThread]); // 會打印
dispatch_sync(dispatch_get_main_queue(), ^{
     NSLog(@"當前線程----->%@",[NSThread currentThread]);  // 這句話永遠不會打印,此時主線程已經(jīng)阻塞了裆针,你對界面的所有操作都沒反應(yīng)了刨摩。
});
NSLog(@"當前線程----->%@",[NSThread currentThread]); // 不會打印

原因:
1.dispatch_sync同步任務(wù)寺晌,不會開啟新的線程,所以上面的代碼是在主線程中執(zhí)行的澡刹,也就會阻塞主線程呻征,等待block中的任務(wù)完成。
2.dispatch_get_main_queue()主隊列罢浇,會把block中的任務(wù)放進主隊列陆赋,也就是主線程中去執(zhí)行,可是此時主線程已經(jīng)阻塞了嚷闭,block永遠無法完成任務(wù)攒岛。所以就會一直阻塞主線程。

實例2:

    // 自定義串行隊列
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
    
    // 串行異步
    dispatch_async(queue, ^{  // @1
        NSLog(@"當前線程----->%@",[NSThread currentThread]); // 會打印
        dispatch_sync(queue, ^{ // 不會打印  @2
             NSLog(@"當前線程1----->%@",[NSThread currentThread]);
        });
        NSLog(@"當前線程2----->%@",[NSThread currentThread]); // 不會打印
    });
    NSLog(@"當前線程3----->%@",[NSThread currentThread]); // 會打印 @3

原因:
1.上面的代碼@1會開啟一條新的線程胞锰,但因為是在串行隊列中灾锯,所以會一個一個執(zhí)行任務(wù)。我們假設(shè)開啟的新線程叫“B”;
2.打印完"當前線程"后嗅榕,@2同步任務(wù)顺饮,不會開啟新的線程,會阻塞當前線程凌那,所以還是在"B"線程中執(zhí)行任務(wù)兼雄,此時線程"B"已經(jīng)阻塞了,@2會把block當中的任務(wù)放入"myQueue"中去執(zhí)行帽蝶,但是"myQueue"是串行的赦肋,所以必須等"myQueue"執(zhí)行完上一個任務(wù),而它執(zhí)行的上一個任務(wù)就是當前block中的任務(wù)嘲碱,也就是阻塞了的@2,@2永遠執(zhí)行不了金砍,所以會一直阻塞。
3.@3會打印麦锯,是因為它是在主線程中的恕稠。

實例3:

    // 創(chuàng)建并行隊列
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{ // @1
        NSLog(@"當前線程----->%@",[NSThread currentThread]);
        dispatch_sync(queue, ^{ // @2
            NSLog(@"當前線程1----->%@",[NSThread currentThread]);
        });
        NSLog(@"當前線程2----->%@",[NSThread currentThread]); // @3
    });
    NSLog(@"當前線程3----->%@",[NSThread currentThread]); // @4
    -----------------------------以上都會打印-----------------------------

原因:
1.@1會開啟至少一條新的線程,并行執(zhí)行任務(wù)扶欣。
2.@2不會開啟新的線程鹅巍,在當前線程并行執(zhí)行任務(wù)。會阻塞當前線程料祠,但因為是并行隊列中骆捧,所以會執(zhí)行完@2,在執(zhí)行@3.
3.@3在主線程中執(zhí)行,不受影響髓绽。

隊列組

    // 創(chuàng)建組
    dispatch_group_t group = dispatch_group_create();
    // 系統(tǒng)全局唯一并行隊列
    //dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 自定義串行隊列敛苇,按順序執(zhí)行
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
    
    dispatch_group_async(group, queue, ^{ // @1
        NSLog(@"當前線程----->%@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{ // @2
        NSLog(@"當前線程1----->%@",[NSThread currentThread]);
    });
    dispatch_group_async(group, queue, ^{ // @3
        NSLog(@"當前線程2----->%@",[NSThread currentThread]);
    });
    
    dispatch_group_notify(group, queue, ^{ // @4
        NSLog(@"當前線程3----->%@",[NSThread currentThread]);
    });
  • 并行隊列
    @1,2顺呕,3會隨機打印枫攀,最后打印@4
  • 串行隊列
    @1<@2<@3<@4 按順序打印

單列

 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
 });

延時執(zhí)行

    // 如果在串行括饶、并行隊列中執(zhí)行,會開啟線程来涨。也就是說dispatch_after方法是異步執(zhí)行的
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"當前線程----->%@",[NSThread currentThread]);
    });

柵欄方法(分割任務(wù))

    // dispatch_barrier_async 方法需使用自定義隊列图焰,不能使用系統(tǒng)全局隊列
    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    //dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{ // @1
        NSLog(@"當前線程----->%@",[NSThread currentThread]);
    });
    
    dispatch_barrier_async(queue, ^{ // @2
        NSLog(@"當前線程1----->%@",[NSThread currentThread]);
    });
    
    dispatch_async(queue, ^{ // @3
        NSLog(@"當前線程2----->%@",[NSThread currentThread]);
    });

注意:
使用dispatch_barrier_async時:
1.必須使用自定義隊列,不能使用系統(tǒng)全局隊列蹦掐。
dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT)


NSOperation&NSOperationQueue

NSOperation是Apple對GCD的封裝技羔,是面向?qū)ο蟮摹SOperation卧抗、NSOperationQueue分別對應(yīng)GCD中的任務(wù)和隊列藤滥。

注意:NSOperation是個抽象類,不能直接使用颗味,必須使用它的2個子類:NSInvocationOperation超陆、NSBlockOperation。

創(chuàng)建任務(wù):

  • NSInvocationOperation
NSInvocationOperation *invocationOP = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
[invocationOP start];
  • NSBlockOperation
 NSBlockOperation *blockOP = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"當前線程---->%@",[NSThread currentThread]);
 }];

[blockOP addExecutionBlock:^{
        NSLog(@"當前線程1---->%@",[NSThread currentThread]);
}];
[blockOP start];

注意:
1.addExecutionBlock方法可能開啟新的線程浦马,也可能在主線程中執(zhí)行时呀。
2.addExecutionBlock方法調(diào)用必須在start方法之前,否則會報錯晶默。

  • 自定義任務(wù):新建一個類繼承NSOperation谨娜,需要重寫main,cancel,finished,executing等方法。

創(chuàng)建隊列:(只有主隊列磺陡,和其他隊列趴梢,沒有串行和并行區(qū)分)

  • NSOperationQueue(其他隊列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
  • 主隊列
[NSOperationQueue mainQueue];
使用:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1; // 串行,默認為-1不限制币他,既并行
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"當前線程---->%@",[NSThread currentThread]);
 }];
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"當前線程1---->%@",[NSThread currentThread]);
 }];
[queue addOperation:operation];
[queue addOperation:operation1];

注意:任務(wù)加入隊列中坞靶,會自動執(zhí)行,不需要調(diào)用start方法蝴悉,否則會報錯彰阴。

依賴

必須等A任務(wù)執(zhí)行完畢之后在執(zhí)行B任務(wù)。
比如從網(wǎng)上開啟一個線程下載圖片拍冠,必須等圖片下載完成之后在主線程加載圖片尿这,刷新UI,這個時候就可以用上依賴了庆杜。

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    //queue.maxConcurrentOperationCount = 1; // 串行射众,默認為-1不限制
    
    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"當前線程---->%@",[NSThread currentThread]);
    }];
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"當前線程1---->%@",[NSThread currentThread]);
    }];
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"當前線程2---->%@",[NSThread currentThread]);
    }];
    
    [operation addDependency:operation1]; // operation依賴operation1
    [operation2 addDependency:operation]; // 2operation依賴operation
    [queue addOperations:@[operation,operation1] waitUntilFinished:NO];
    [NSOperationQueue.mainQueue addOperation:operation2];

2017-08-10 10:46:34.938 ZTSlidingVC[1273:222606] 當前線程1----><NSThread: 0x7fd9f3dd9510>{number = 2, name = (null)}
2017-08-10 10:46:34.938 ZTSlidingVC[1273:222606] 當前線程----><NSThread: 0x7fd9f3dd9510>{number = 2, name = (null)}
2017-08-10 10:46:34.948 ZTSlidingVC[1273:222557] 當前線程2----><NSThread: 0x7fd9f3d287a0>{number = 1, name = main}

注意:依賴關(guān)系是可以跨隊列的,如上面例子所示晃财。

其他屬性叨橱、方法

  • NSOperation
屬性:
@property (readonly, getter=isCancelled) BOOL cancelled; // 是否取消任務(wù)
@property (readonly, getter=isExecuting) BOOL executing; // 是否正在執(zhí)行
@property (readonly, getter=isFinished) BOOL finished; // 是否完成任務(wù)
方法:
- (void)cancel; // 取消任務(wù)
- (void)start; // 開始任務(wù)
- (void)addDependency:(NSOperation *)op; // 添加依賴
- (void)removeDependency:(NSOperation *)op; // 刪除依賴
  • NSOperationQueue
屬性:
@property (readonly) NSUInteger operationCount NS_AVAILABLE(10_6, 4_0); // 獲取隊列中的任務(wù)數(shù)量
@property NSInteger maxConcurrentOperationCount; // 設(shè)置最大任務(wù)數(shù)
@property (getter=isSuspended) BOOL suspended; // YES:暫停,NO:繼續(xù)(對正在執(zhí)行的任務(wù)無效,只是暫停調(diào)度新的任務(wù)執(zhí)行)
@property (class, readonly, strong, nullable) NSOperationQueue *currentQueue NS_AVAILABLE(10_6, 4_0); // 獲取當前隊列
@property (class, readonly, strong) NSOperationQueue *mainQueue NS_AVAILABLE(10_6, 4_0); // 獲取主隊列
方法:
- (void)cancelAllOperations; // 取消所有任務(wù)
- (void)waitUntilAllOperationsAreFinished; // 等待所有隊列中的任務(wù)執(zhí)行完成罗洗,會阻塞線程(在等待時嘉裤,其他線程仍然可以往隊列中添加任務(wù))

線程同步

  • 為什么需要線程同步:
    當多個線程同時訪問一個統(tǒng)一資源,造成數(shù)據(jù)狀態(tài)不一致栖博,產(chǎn)生的數(shù)據(jù)混亂,安全等問題厢洞。
  • 實現(xiàn)線程同步的2種方式:
    1.加鎖
  1. @synchronized 關(guān)鍵字加鎖
  2. NSLock 對象鎖
  3. NSCondition
  4. NSConditionLock 條件鎖
  5. NSRecursiveLock 遞歸鎖
  6. pthread_mutex 互斥鎖(C語言)
  7. dispatch_semaphore 信號量實現(xiàn)加鎖(GCD)
  8. OSSpinLock

方法有點多仇让,這就不一一介紹了,開發(fā)中也用不了這么多躺翻。這里就簡單介紹一下1丧叽,2,7的使用把公你,需要其他更詳細的的功能請自行g(shù)oolge踊淳。

  • @synchronized 關(guān)鍵字加鎖(性能較差,使用簡單)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        @synchronized (self) {
            NSLog(@"做你想做的事");
        }
 });
  • NSLock(性能一般)
NSLock *lock = [[NSLock alloc] init];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        if ([lock tryLock]) { // 嘗試加鎖陕靠,如果失敗了迂尝,并不會阻塞線程,只是立即返回NO
            NSLog(@"做你想做的事");
            [lock unlock]; // 記得解鎖
        }
});
  • dispatch_semaphore 信號量實現(xiàn)加鎖(GCD,推薦使用此方法)

dispatch_semaphore_create   創(chuàng)建一個semaphore
dispatch_semaphore_signal   發(fā)送一個信號(計數(shù)器+1)
dispatch_semaphore_wait    等待信號(信號量-1剪芥,如果信號量<=0垄开,則一直等待,會阻塞線程)

dispatch_semaphore_t dsema = dispatch_semaphore_create(2); // 創(chuàng)建信號量,后面的數(shù)字既最大并發(fā)量
    for(int i=0; i<10; i++){
        dispatch_semaphore_wait(dsema, DISPATCH_TIME_FOREVER);  // -1 DISPATCH_TIME_FOREVER會一直等待,直到信號量大于0税肪。DISPATCH_TIME_NOW不等待溉躲,也就不能控制線程并發(fā)數(shù)了。
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSLog(@"------>%d  當前線程---->%@",i,[NSThread currentThread]);
            dispatch_semaphore_signal(dsema); // +1
        });
    }

上面的列子益兄,看起來創(chuàng)建了10個線程锻梳,其實同時只有2個線程在并發(fā)執(zhí)行。

2.使用串行隊列

參考:

http://www.reibang.com/p/0b0d9b1f1f19
http://ksnowlv.github.io/blog/2014/09/07/ios-tong-bu-suo-xing-neng-dui-bi/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末净捅,一起剝皮案震驚了整個濱河市疑枯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌灸叼,老刑警劉巖神汹,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異古今,居然都是意外死亡屁魏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門捉腥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來氓拼,“玉大人,你說我怎么就攤上這事√已” “怎么了坏匪?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長撬统。 經(jīng)常有香客問我适滓,道長,這世上最難降的妖魔是什么恋追? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任凭迹,我火速辦了婚禮,結(jié)果婚禮上苦囱,老公的妹妹穿的比我還像新娘嗅绸。我一直安慰自己,他們只是感情好撕彤,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布鱼鸠。 她就那樣靜靜地躺著,像睡著了一般羹铅。 火紅的嫁衣襯著肌膚如雪蚀狰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天睦裳,我揣著相機與錄音造锅,去河邊找鬼。 笑死廉邑,一個胖子當著我的面吹牛哥蔚,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛛蒙,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼糙箍,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了牵祟?” 一聲冷哼從身側(cè)響起深夯,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎诺苹,沒想到半個月后咕晋,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡收奔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年掌呜,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坪哄。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡质蕉,死狀恐怖势篡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情模暗,我是刑警寧澤禁悠,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站兑宇,受9級特大地震影響碍侦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜隶糕,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一祝钢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧若厚,春花似錦、人聲如沸蜒什。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灾常。三九已至霎冯,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間钞瀑,已是汗流浹背沈撞。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留雕什,地道東北人缠俺。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像贷岸,于是被迫代替她去往敵國和親壹士。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

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