iOS線程基礎知識總結(jié)

一, 程序良姆、進程和線程
程序:由源代碼生成的可執(zhí)行應用
進程: 一個正在運行的程序可以看做是一個進程
線程:程序中獨立運行的代碼段。
一個進程是由一個或多個線程組成。進程只負責資源的調(diào)度和分配堕汞, 線程才是程序真正的執(zhí)行單元, 負責代碼的執(zhí)行晃琳。
線程和進程的區(qū)別:
1讯检, 地址空間:線程是進程內(nèi)的一個執(zhí)行單元;進程至少有一個線程卫旱, 他們共享進程的地址空間人灼; 而地址有自己的獨立的地址空間;
2顾翼, 資源擁有:進程是資源分配和擁有的單位投放, 同一個進程內(nèi)的線程共享進程的資源;
3适贸, 線程是處理器調(diào)度的基本單位灸芳, 而進程不是涝桅;
4, 二者都可以并發(fā)執(zhí)行
**************iOS中關于UI的添加和刷新必須在主線程中操作
二烙样, 多線程的實現(xiàn)種類
iOS中多線程的實現(xiàn)種類有:NSThread冯遂,NSObject,NSOperationQueue谒获,GCD
1, NSThread是一個輕量級的多線程蛤肌, 有以下兩種創(chuàng)建方式:
(1)初始化開辟子線程

- (void)allocThread {

    //初始化開辟子線程
    //object 就是子線程方法的參數(shù)
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(threadAction:) object:@1000];
    //*********初始化開辟線程的話需要手動開啟
    thread.name = @"zhengzhou";
//    _thread.isCancelled 是否被取消
//    _thread.isExecuting 是否正在執(zhí)行
//    _thread.isMainThread 是否是主線程
    [thread start];
}

- (void)threadAction:(NSNumber *)number {
    
    //使用NSThread開辟的子線程, 方法內(nèi)部默認沒有添加自動釋放池, 為了防止內(nèi)存泄露, 我們需要手動添加自動釋放池
    @autoreleasepool {
        for (int i = 0; i < [number integerValue]; i++) {
            NSLog(@"%@", [NSThread currentThread]);
            if (i == 100) {
                // cancle 并不能取消正在執(zhí)行的線程,只能取消還沒有開始執(zhí)行的線程
                [[NSThread currentThread] cancel];
                // 立即停止線程
                [NSThread exit];
            }
            NSLog(@"%d", i);
        }
    }
}

(2)便利構造器開辟子線程

//不需要手動開啟
[NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@1000];

我們一般不用NSThread來開辟子線程
2, NSObject

//NSObject
- (void)objectAction {
    //開辟子線程
    [self performSelectorInBackground:@selector(reuestImageData:) withObject:@100];
}

//子線程方法
- (void)reuestImageData:(NSString *)string {
    //手動添加自動釋放池
    @autoreleasepool {
        
        //回到主線程刷新UI
        //最后一個參數(shù)為YES時批狱, 是等主線程的方法執(zhí)行完之后在執(zhí)行線程后面的方法
        //最后一個參數(shù)為NO時裸准, 是主線程和子線程中的方法同時執(zhí)行
        [self performSelectorOnMainThread:@selector(updateUI:) withObject:nil waitUntilDone:NO];
        for (int i = 0; i < 10; i++) {
            NSLog(@"%d********%@", i, [NSThread currentThread]);
        }
    }
}
//刷新UI
- (void)updateUI:(NSData *)data {
    
    for (int i = 0; i < 10; i++) {
        NSLog(@"%d+++++++++%@", i, [NSThread currentThread]);
    }
}

3, NSOperationQueue
NSOperation在MVC中屬于M赔硫,是用來封裝單個任務相關的代碼和數(shù)據(jù)的抽象類炒俱,不能夠直接使用這個類,而是使用子類(NSInvocationOperation或NSBlockOperation)來執(zhí)行實際任務卦停。
只是一個操作向胡,本身無主線程子線程之分,可在任意線程中使用惊完。通常與NSOperationQueue結(jié)合使用僵芹,只是封裝了一定的代碼段和數(shù)據(jù)去實現(xiàn)一個功能。

- (void)invocationOperationAction {
    //NSOperation的子類, 創(chuàng)建的操作和線程沒有關系, 在主線程中創(chuàng)建的操作, 方法在主線程中進行, 在子線程中創(chuàng)建的操作在子線程中進行
    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationOperationMethod:) object:@"hello"];
    //需要手動開啟任務
    [operation start];
    //取消任務
    //    [operation cancel];
    //是否正在執(zhí)行
    //    [operation isExecuting];
    //是否完成任務
    //    [operation isFinished];
}

- (void)invocationOperationMethod:(NSString *)string {
    NSLog(@"%@", [NSThread currentThread]);
    NSLog(@"%@", string);
}
// NSBlockOperation
- (void)blockOperation {
    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        //執(zhí)行的方法
        NSLog(@"%@", [NSThread currentThread]);
    }];
    //需要手動開啟
    [blockOperation start];
}

NSOperationQueue是操作隊列, 用來管理一組Operation對象的執(zhí)行, 會根據(jù)需要自動為Operation開辟合適數(shù)量的線程, 已完成任務的執(zhí)行
其中NSOperation可以調(diào)節(jié)它在隊列中的優(yōu)先級(使用addDependency: 設置依賴關系)
當最大并發(fā)數(shù)設置為1的時候, 能實現(xiàn)線程同步(串行執(zhí)行)

- (void)operationQueue {
    NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 1000000; i++) {
            NSLog(@"1 ------ %d", i);
        }
    }];
    NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
        for (int i = 0; i < 1000000; i++) {
            NSLog(@"2 ------ %d", i);
        }
    }];
    //創(chuàng)建一個新的隊列
    //新創(chuàng)建的隊列, 里面的任務是并發(fā)執(zhí)行的, 而且是在子線程中執(zhí)行的
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    //設置任務最大并發(fā)數(shù), 如果為1, 隊列里邊的任務相當于串行
    //    queue.maxConcurrentOperationCount = 1;
    
    //添加依賴關系, 必須在任務添加到隊列之前設置
    [blockOperation1 addDependency:blockOperation2];
    
    [queue addOperation:blockOperation1];
    [queue addOperation:blockOperation2];
    
}

4小槐,GCD(Grand Central Dispatch)
是Apple開發(fā)的一種多核編程技術. 主要用于優(yōu)化應用程序一支持多核處理器以及其他對稱多處理系統(tǒng)
GCD提供函數(shù)實現(xiàn)多線程開發(fā), 性能更高, 功能也更加強大
首次發(fā)布在Mac OS X 10.6, iOS4以上可用

核心概念:
任務: 具有一定功能的代碼段, 一般是一個block或者函數(shù)拇派, 與NSOperation一樣,并無主線程與子線程之分凿跳,主要是看它加載在什么queue隊列中
分發(fā)隊列: GCD隊列的方式進行工作
GCD會根據(jù)分發(fā)隊列的類型, 創(chuàng)建合適數(shù)量的線程執(zhí)行隊列中的任務

dispatch queue有串行隊列和并發(fā)隊列兩種:
(1)串行隊列(SerialQueue):一次只執(zhí)行一個任務. 一般用于同步訪問特定的資源和數(shù)據(jù). 當創(chuàng)建多個SerialQueue時, 雖然他們是同步執(zhí)行的, 但他們之間是并發(fā)執(zhí)行的.SerialQueue能實現(xiàn)線程同步

//主隊列
- (void)mainQueueAction {
    //獲取主隊列
    dispatch_queue_t queue = dispatch_get_main_queue();
    //主隊列中添加任務
    dispatch_async(queue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"-------------------%@", [NSThread mainThread]);
        }
    });
    //主隊列中添加任務
    dispatch_async(queue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"++++++++++++++++++++%@", [NSThread mainThread]);
        }
    });
}

//自定義串行隊列
- (void)customSerialQueue {
    //創(chuàng)建一個串行隊列
    //參數(shù):(1)隊列的名字, (2)隊列類型, 是串行還是并行
    //串行里面的任務是在同一個線程中執(zhí)行的
    dispatch_queue_t serialQueue = dispatch_queue_create("com.lanou3g.serialQueue", DISPATCH_QUEUE_SERIAL);
    dispatch_async(serialQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"---------------------%@", [NSThread currentThread]);
        }
    });
    dispatch_async(serialQueue, ^{
        for (int i = 0; i < 100; i++) {
            NSLog(@"++++++++++++++++++++%@", [NSThread currentThread]);
        }
    });
}

(2)并發(fā)隊列(Concurrent):可以并發(fā)地執(zhí)行多個任務

//全局隊列
- (void)globalQueue {
    //參數(shù): (1)參數(shù)優(yōu)先級, (2)預留參數(shù)
    //隊列里面的任務并發(fā)執(zhí)行
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //添加任務
    dispatch_async(globalQueue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"----------%@", [NSThread currentThread]);
        }
    });
    dispatch_async(globalQueue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"+++++++++++%@", [NSThread currentThread]);
        }
    });
}
//自定義并發(fā)隊列
- (void)customConcurrentQueue {
    dispatch_queue_t concurrentQueue = dispatch_queue_create("com.lanou3g.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(concurrentQueue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"------------------%@", [NSThread currentThread]);
        }
    });
    dispatch_async(concurrentQueue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"+++++++++++++++++++%@", [NSThread currentThread]);
        }
    });
}

(3)GCD功能
GCD功能
dispatch_async() //往隊列中添加任務, 任務會排隊執(zhí)行
dispatch_after() //往隊列中添加任務, 任務不但會排隊, 還會在延遲的時間點執(zhí)行

//延遲執(zhí)行任務
- (void)delayPerformQueue {
    dispatch_queue_t queue = dispatch_queue_create("com.lanou3g.delayPerformQueue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"%@", [NSThread currentThread]);
        }
    });
    //延遲執(zhí)行任務
    //queue隊列里面的任務執(zhí)行完成之后, 延遲5秒執(zhí)行該函數(shù)里面的任務
    //不能在主隊列中執(zhí)行該任務
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"延遲執(zhí)行的任務");
    });
}

dispatch_apply() //往隊列中添加任務, 任務會重復執(zhí)行n次

//重復執(zhí)行任務
- (void)repeatPerformTask {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //注意: queue 參數(shù)不能是主隊列(死鎖)
    dispatch_apply(10, queue, ^(size_t index) {
        NSLog(@"%ld, %@", index, [NSThread currentThread]);
    });
}

dispatch_group_async()//將任務添加到隊列中, 并添加分組標記
dispatch_group_notify() //將任務添加到隊列中, 當某個分組的所有任務執(zhí)行完之后, 此任務才會執(zhí)行

//分組標記功能
- (void)groupTask {
    dispatch_queue_t queue = dispatch_queue_create("waige", DISPATCH_QUEUE_CONCURRENT);
    //創(chuàng)建分組
    dispatch_group_t group = dispatch_group_create();
    //往隊列里面添加任務1
    dispatch_group_async(group, queue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"------------%@", [NSThread currentThread]);
        }
    });
    
    //往隊列里面添加任務2
    dispatch_group_async(group, queue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"+++++++++++++++%@", [NSThread currentThread]);
        }
    });
    
    //給隊列添加任務, 并添加分組標記
    dispatch_group_notify(group, queue, ^{
        NSLog(@"queue里面的所有任務都已經(jīng)執(zhí)行完畢");
    });
    
}

dispatch_barrier_async() //將任務添加到隊列中, 此任務執(zhí)行的時候, 其他任務停止執(zhí)行

//添加障礙
- (void)barrierFunction {
    //創(chuàng)建隊列
    dispatch_queue_t queue = dispatch_queue_create("waige", DISPATCH_QUEUE_CONCURRENT);
    //添加任務
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"寫入數(shù)據(jù)");
        }
    });
    //設置屏障, 隊列里面前面的任務執(zhí)行完之后才執(zhí)行屏障函數(shù)里面的任務
    dispatch_barrier_async(queue, ^{
        for (int i = 0; i < 20; i++) {
            NSLog(@"不要打擾我, 哥在寫數(shù)據(jù)呢");
        }
    });
    //屏障函數(shù)的任務完成之后才會執(zhí)行下面的任務
    dispatch_async(queue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"寫完了, 大家可以讀數(shù)據(jù)了");
        }
    });
}

dispatch_once() //任務添加到隊列中, 但任務在程序運行過程中, 只執(zhí)行一次
可用于單例的創(chuàng)建
該函數(shù)接收一個dispatch_once用于檢查該代碼塊是否已經(jīng)被調(diào)度的謂詞(是一個長整型, 實際上作為BOOL使用), 它在接收一個希望在應用的生命周期內(nèi)僅被調(diào)度一次的代碼塊. 不僅意味著代碼僅會被運行一次, 而且還是線程安全的, 這就意味著你不需要使用諸如@synchronized之類的來防止使用多個線程或者隊列時不同步的問題

+ (instancetype)sharedSingleTon {
    static SingleTon *singleTon = nil;
    //只能同時允許一個線程訪問
    @synchronized(self) {
        if (singleTon == nil) {
            singleTon = [[SingleTon alloc] init];
        }
    }
    return singleTon;
}

//GCD創(chuàng)建單例
+ (instancetype)defaultSingleTon {
    static SingleTon *single = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //這里的代碼只執(zhí)行一次
        single = [[SingleTon alloc] init];
    });
    return single;
}

dispatch_sync() //將任務添加到隊列中, block不執(zhí)行完, 下面代碼不會執(zhí)行(同步),會阻塞當前線程 ----------在當前線程中執(zhí)行
dispatch_async_f() //將任務添加到隊列中, 任務是函數(shù)非block(異步)---------重新創(chuàng)建線程執(zhí)行任務

//同步
- (void)useOfSync {
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //dispatch_sync會阻塞當前線程
    dispatch_sync(queue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"%@", [NSThread currentThread]);
            
        }
    });
    NSLog(@"這是一條分割線");
    dispatch_sync(queue, ^{
        for (int i = 0; i < 10; i++) {
            NSLog(@"=====%@", [NSThread currentThread]);
        }
    });
    NSLog(@"這又是一條分割線");
}

三件豌,線程間的通信
子線程回到主線程的方法

//bool參數(shù) 如果是YES, 子線程會等待主線程的任務完成以后才會繼續(xù)執(zhí)行, 如果為NO, 主線程的任務沒有結(jié)束的時候就會執(zhí)行子線程的任務
        [self performSelectorOnMainThread:@selector(updataUI:) withObject:data waitUntilDone:NO];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imageView.image = [UIImage imageWithData:data];
        });
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            self.imageView.image = [UIImage imageWithData:data];
        }];

四,線程互斥
對線程并行編程中, 線程間的同步和互斥是一個很有技巧的也很容易出錯的地方控嗜。
多線程操作同一個資源(即某個對象), 需要保證線程在對資源的狀態(tài)(即對象的成員變量)進行一些非原子性操作后, 狀態(tài)仍然正確茧彤。
情景: 三個售票窗口同時售票, 可只剩最后一張票, 如何解決
解決方案
1,@synchronized 自動對參數(shù)對象加鎖, 保證臨街區(qū)內(nèi)的代碼線程安全
2疆栏,NSLock

//創(chuàng)建一個并行隊列
    dispatch_queue_t queue = dispatch_queue_create("zz", DISPATCH_QUEUE_CONCURRENT);
    //創(chuàng)建鎖對象
        NSLock *lock = [[NSLock alloc] init];
    //開辟10個子線程, 進行售票
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            //加鎖
            [lock lock];
            //售票任務
            while (self.ticketsCount > 0) {
                //線程休息0.1秒
                [NSThread sleepForTimeInterval:0.1];
                //售出一張
                self.ticketsCount--;
                NSLog(@"剩余票數(shù):%ld, 當前線程:%@", self.ticketsCount, [NSThread currentThread]);
            }
            //解鎖
            [lock unlock];
        });
    }

3曾掂,NSConditionLock條件鎖 可以設置條件

//創(chuàng)建一個并行隊列
    dispatch_queue_t queue = dispatch_queue_create("zz", DISPATCH_QUEUE_CONCURRENT);
    //條件鎖
    NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:2];;
    //開辟10個子線程, 進行售票
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            //條件鎖
            [lock lockWhenCondition:2];
            //售票任務
            while (self.ticketsCount > 0) {
                //線程休息0.1秒
                [NSThread sleepForTimeInterval:0.1];
                //售出一張
                self.ticketsCount--;
                NSLog(@"剩余票數(shù):%ld, 當前線程:%@", self.ticketsCount, [NSThread currentThread]);
            }
            //解鎖
            [lock unlockWithCondition:2];
        });
    }

4,NSRecursiveLock 遞歸鎖 多次調(diào)用不會阻塞以獲取該鎖的線程

//創(chuàng)建一個并行隊列
    dispatch_queue_t queue = dispatch_queue_create("zz", DISPATCH_QUEUE_CONCURRENT);
    //遞歸鎖
    recursiveLock = [[NSRecursiveLock alloc] init];
    //開辟10個子線程, 進行售票
    for (int i = 0; i < 10; i++) {
        dispatch_async(queue, ^{
            //遞歸鎖
            [recursiveLock lock];
            //售票任務
            while (self.ticketsCount > 0) {
                //線程休息0.1秒
                [NSThread sleepForTimeInterval:0.1];
                //售出一張
                self.ticketsCount--;
                NSLog(@"剩余票數(shù):%ld, 當前線程:%@", self.ticketsCount, [NSThread currentThread]);
            }
            //解鎖
            [recursiveLock unlock];
        });
    }

五壁顶,總結(jié)
NSThread, NSOperationQueue, NSObject, GCD 都能實現(xiàn)多線程
1珠洗,GCD是蘋果提供的性能更高的方式
使用多線程開發(fā)的優(yōu)點: 資源利用率更好, 程序設計在某些情況下更簡單, 程序響應更快
缺點: 多線程金環(huán)提升了性能, 但是存在一些訪問限制, 比如線程同步, 線程互斥等; 多線程在使用的時候, 最終是要回到主線程刷新UI的, 如果開辟過多的多線程, 會造成CPU的消耗

2,NSOperationQueue和GCD 的區(qū)別
(1)GCD是基于C語言構成的API, 而NSoperationQueue是NSObject對象,在GCD 中在隊列中執(zhí)行的是由block構成的任務, 而NSOperationQueue有兩種方式可供選擇:NSInvocationOperation和NSBlockOperation
(2)在NSOperationQueue中可以隨時取消正在等待執(zhí)行隊列, 而GCD無法停止已經(jīng)加入queue隊列的block塊(其實是有的, 只不過代碼比較復雜)
(3)在NSOperation中我們可以為任務設定依賴關系,
(4)我們可以講KVO應用在NSOperation對象中, 可以監(jiān)聽一個operation是否完成或取消, 這樣可以更有效的掌控我們的后臺任務
(5)在NSOperation中我們可以設置NSOperation的priority的優(yōu)先級, 能夠使同一個并行的序列中的任務區(qū)分先后的執(zhí)行, 而在GCD中, 我們只能區(qū)分不同任務隊列的優(yōu)先級, 如果要區(qū)分block任務的優(yōu)先級, 也需要大量的代碼
(6)我們能夠?qū)SOperation進行繼承, 在這智商添加成員變量與成員方法, 提高整個代碼的復用度, 這筆簡單地將block任務排入執(zhí)行隊列更有自由度, 能夠在其之上添加更多自定制的功能

3若专,OperationQueue提供了更多在編寫多線程程序時需要的功能, 并隱藏了許多線程調(diào)度, 線程取消與線程優(yōu)先級的復雜代碼, 為我們提供簡單API入口. 從編程原則來說, 一般我們需要盡可能的使用最高等級, 封裝完美的API, 在必須時才使用底層的API.
GCD更簡潔, 性能更好,而NSOperationQueue為我們提供了更多的選擇

最后編輯于
?著作權歸作者所有,轉(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)容