ios多線程

  • 什么是進(jìn)程

  • 進(jìn)程是指在系統(tǒng)中正在運(yùn)行的一個應(yīng)用程序

  • 每個進(jìn)程之間是獨(dú)立的,每個進(jìn)程均運(yùn)行在其專用且受保護(hù)的內(nèi)存空間內(nèi)

  • 比如同時打開迅雷筐喳、Xcode贺待,系統(tǒng)就會分別啟動2個進(jìn)程

  • 什么是線程

  • 1個進(jìn)程要想執(zhí)行任務(wù),必須得有線程(每1個進(jìn)程至少要有1條線程)

  • 一個進(jìn)程(程序)的所有任務(wù)都在線程中執(zhí)行

  • 比如使用酷狗播放音樂临庇、使用迅雷下載電影反璃,都需要在線程中執(zhí)行

  • 1個線程中任務(wù)的執(zhí)行是串行的

  • 如果要在1個線程中執(zhí)行多個任務(wù),那么只能一個一個地按順序執(zhí)行這些任務(wù)

  • 也就是說假夺,在同一時間內(nèi)淮蜈,1個線程只能執(zhí)行1個任務(wù)

什么是多線程
  • 1個進(jìn)程中可以開啟多條線程,每條線程可以并行(同時)執(zhí)行不同的任務(wù)
  • 多線程技術(shù)可以提高程序的執(zhí)行效率
  • 比如同時開啟3條線程分別下載3個文件(分別是文件A侄泽、文件B礁芦、文件C
多線程的原理
  • 同一時間,CPU只能處理1條線程,只有1條線程在工作(執(zhí)行)
  • 多線程并發(fā)(同時)執(zhí)行柿扣,其實(shí)是CPU快速地在多條線程之間調(diào)度(切換)
  • 如果CPU調(diào)度線程的時間足夠快肖方,就造成了多線程并發(fā)執(zhí)行的假象

如果線程非常非常多,會發(fā)生什么情況未状?
CPU會在N多線程之間調(diào)度俯画,CPU會累死,消耗大量的CPU資源
每條線程被調(diào)度執(zhí)行的頻次會降低(線程的執(zhí)行效率降低)

多線程的優(yōu)點(diǎn)
  • 能適當(dāng)提高程序的執(zhí)行效率
  • 能適當(dāng)提高資源利用率(CPU司草、內(nèi)存利用率)
多線程的缺點(diǎn)
  • 創(chuàng)建線程是有開銷的艰垂,iOS下主要成本包括:內(nèi)核數(shù)據(jù)結(jié)構(gòu)(大約1KB)、椔窈纾空間(子線程512KB猜憎、主線程1MB,也可以使用-setStackSize:設(shè)置搔课,但必須是4K的倍數(shù)胰柑,而且最小是16K),創(chuàng)建線程大約需要90毫秒的創(chuàng)建時間
  • 如果開啟大量的線程爬泥,會降低程序的性能
  • 線程越多柬讨,CPU在調(diào)度線程上的開銷就越大
  • 程序設(shè)計(jì)更加復(fù)雜:比如線程之間的通信、多線程的數(shù)據(jù)共享
什么是主線程
  • 一個iOS程序運(yùn)行后袍啡,默認(rèn)會開啟1條線程踩官,稱為“主線程”或“UI線程”

  • 主線程的主要作用

    • 顯示\刷新UI界面
    • 處理UI事件(比如點(diǎn)擊事件、滾動事件境输、拖拽事件等)
  • 主線程的使用注意

    • 別將比較耗時的操作放到主線程中
    • 耗時操作會卡住主線程蔗牡,嚴(yán)重影響UI的流暢度,給用戶一種“卡”的壞體驗(yàn)

在主線程放一個需要耗時10秒的操作;用戶在第五秒的時候點(diǎn)擊屏幕按鈕,在第十秒的時候才會做出響應(yīng);造成卡頓現(xiàn)象;

  • 在ios領(lǐng)域里面真正的多線程技術(shù)只有這兩個pthread和NSthread;
    GCD不能直接操作多線程;屬于并發(fā)技術(shù);NSOperation也是一樣,是操作隊(duì)列的,與線程無關(guān),線程部分GCD已經(jīng)幫你封裝好了!
  • GCD會自動管理線程的生命周期(創(chuàng)建線程畴嘶、調(diào)度任務(wù)蛋逾、銷毀線程)
  • 我們只需要告訴GCD想要執(zhí)行什么任務(wù),不需要編寫任何線程管理代碼
  • 蘋果不建議開發(fā)者使用多線程技術(shù);
    鼓勵使用并發(fā)技術(shù);
NSThread
  • 創(chuàng)建線程的幾種方法
// 創(chuàng)建一個NSThread
NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(demo:) object:@"Thread"];
//線程就緒-之后等著cpu調(diào)度; 
[thread start];

//demo函數(shù)在子線程執(zhí)行
-(void)demo:(id)obj{
    for (int i = 0; i < 2; i++) {
        //number !=1
        NSLog(@"%@",[NSThread currentThread]);
        //[NSThread currentThread] 打印當(dāng)前線程   
        //返回一個Thread對象,里面有number和name屬性
        //number == 1 說明是主線程   number != 1 就是其他線程
    }
}

//detach ==> 分離
//分離出一條子線程
[NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:@"Detach"];

//InBackground 就是在后臺(子線程)運(yùn)行!!
//是NSObject的分類 意味著所有的繼承NSObject的都可以使用這個方法
//非常方便.不用NSThread對象
[self performSelectorInBackground:@selector(demo:) withObject:@"background"];

線程的狀態(tài)
  • 新建一條線程,線程在可調(diào)度線程池里 (由cpu進(jìn)行調(diào)度的)
  • 當(dāng) [thread start] 的時候,在可調(diào)度線程池里的線程都處于就緒狀態(tài)
  • cpu調(diào)度處于就緒狀態(tài)的線程
  • 運(yùn)行狀態(tài)
  • 線程執(zhí)行完畢之后線程在可調(diào)度線程池取出,干掉;

線程阻塞

  • 當(dāng)運(yùn)行滿足某個條件,會讓線程"睡一會

提示:sleep 方法是類方法,會直接休眠當(dāng)前線程!!

//當(dāng)前線程睡兩秒
[NSThread sleepForTimeInterval:2.0];
//一旦強(qiáng)行終止線程,后續(xù)的所有代碼都不會被執(zhí)行
//注意:在終止線程之前,應(yīng)該要釋放之前分配的對象!!
[NSThread exit];
//創(chuàng)建線程
NSThread * t = [[NSThread alloc]initWithTarget:self selector:@selector(theadStatus) object:nil];
//線程就緒(CPU翻牌)
[t start];

-(void)theadStatus{
    for (int i = 0; i < 20;i++) {
        //阻塞,當(dāng)運(yùn)行滿足某個條件,會讓線程"睡一會"
        //提示:sleep 方法是類方法,會直接休眠當(dāng)前線程!!
        if (i == 8) {
            NSLog(@"睡一會");    
            //睡的是子線程 
            //注意!!! exit會殺掉主線程!但是APP不會掛掉!!
             [NSThread sleepForTimeInterval:2.0];
        }
        NSLog(@"%@  %d",[NSThread currentThread],i);
        
        //當(dāng)線程滿足某一個條件時,可以強(qiáng)行終止的
        //exit 類方法,哥么終止當(dāng)前線程!!!!
        if (i == 15) {
            [NSThread exit];  //線程就就處于死亡狀態(tài)了
        }
    }
    NSLog(@"能來嗎???");  //來不了了
}

threadPriority  //線程優(yōu)先級
  • 優(yōu)先級只是保證cpu調(diào)度的可能性會高!
    用優(yōu)先級來控制線程得執(zhí)行順序是不理性的!
  • 建議:再開發(fā)的時候不要修改優(yōu)先級;
    在多線程的開發(fā)中,不要相信一次的運(yùn)行結(jié)果!
多線程的目的
  • 將耗時操作放在后臺,不阻塞UI線程

多線程的安全隱患

  • 1塊資源可能會被多個線程共享窗悯,也就是多個線程可能會訪問同一塊資源

    • 比如多個線程訪問同一個對象区匣、同一個變量、同一個文件
  • 當(dāng)多個線程訪問同一塊資源時蒋院,很容易引發(fā)數(shù)據(jù)錯亂和數(shù)據(jù)安全問題

安全隱患的解決 - 互斥鎖
  • 一個線程訪問一個資源時,先給他上鎖,訪問完成之后再解鎖讓其他線程訪問;
  • 互斥鎖 -- 保證鎖內(nèi)的代碼,同一時間,只有一條線程執(zhí)行!
  • 互斥鎖 的范圍 應(yīng)該盡量小,范圍大了 效率就差!!
        //互斥鎖
        @synchronized (self) {
            //括號里是 同一時間只能有一條線程執(zhí)行的代碼
        };

好比你去上廁所,你把門鎖上了,別人只能在外面等著,等你操作完廁所,別人才能進(jìn)來;如果你不鎖門,兩個人在廁所后果不堪設(shè)想!??

原子屬性
  • atomic-用來保護(hù)線程安全(多線程執(zhí)行寫入操作的時候,保證同一時間只有一個線程執(zhí)行寫入 只對寫入操作上鎖,讀不上鎖)
  • 單寫多讀的原子屬性(只能單個線程寫,但可以多個線程讀)
  • 實(shí)際上原子屬性內(nèi)部有一把鎖叫 - 自旋鎖
    • 自旋鎖&互斥鎖異同
      • 共同點(diǎn)

        • 都能保證線程安全
      • 不同點(diǎn)

        • 互斥鎖:被鎖在外面的線程,處于休眠狀態(tài);等待鎖打開,然后被喚醒;
        • 自旋鎖:被鎖在外面的線程,用死循環(huán)的方式,等待鎖打開;
  • 不管什么鎖,都很消耗性能,效率不高;

想要模擬原子屬性的時候就在set方法里加了一把鎖; @synchronized
如果不寫nonatomic | atomic 默認(rèn)是 atomic

線程間的通信方法

  • 就這五個方法
    • 把SEL丟到某一個線程去執(zhí)行
/**
 waitUntilDone : 當(dāng)前線程是否等待SEL執(zhí)行完再繼續(xù)
*/

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
    // equivalent to the first method with kCFRunLoopCommonModes

- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array NS_AVAILABLE(10_5, 2_0);
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);
    // equivalent to the first method with kCFRunLoopCommonModes
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg NS_AVAILABLE(10_5, 2_0);


GCD(重點(diǎn))

GCD并不是多線程技術(shù);屬于并發(fā)解決技術(shù);

  • GCD是蘋果為了適配多核的并行運(yùn)算提出的解決方案
  • GCD會自動利用更多的CPU內(nèi)核(比如雙核亏钩、四核)
  • GCD會自動管理線程的生命周期(創(chuàng)建線程、調(diào)度任務(wù)欺旧、銷毀線程)
  • 程序員只需要告訴GCD想要執(zhí)行什么任務(wù)姑丑,不需要編寫任何線程管理代碼
GCD的使用就2個步驟
  • 定制任務(wù)

  • 將任務(wù)添加到隊(duì)列中

GCD中有2個核心概念
  • 任務(wù):執(zhí)行什么操作
    • 執(zhí)行任務(wù)方式有兩種; 同步/異步
      • 同步:不會到線程池里面去獲取子線程!
      • 異步:只要有任務(wù),就會到線程池取子線程!(主隊(duì)列除外!)
  • 隊(duì)列:用來存放任務(wù)
    • 串行:一個接一個的調(diào)度任務(wù)
    • 并行:可以同時調(diào)度多個任務(wù)

GCD會自動將隊(duì)列中的任務(wù)取出,放到對應(yīng)的線程中執(zhí)行
任務(wù)的取出遵循隊(duì)列的FIFO原則:先進(jìn)先出辞友,后進(jìn)后出

/**
 同步執(zhí)行方法,這句話不執(zhí)行完,就不會執(zhí)行下一個任務(wù),同步執(zhí)行不會開啟線程
 */
   //1.創(chuàng)建隊(duì)列
    dispatch_queue_t q = dispatch_get_global_queue(0, 0);
    //2.任務(wù)添加到隊(duì)列中
    //2.1 定義任務(wù) -- block
    void(^task)() = ^{
        NSLog(@"%@",[NSThread currentThread]);
    };
    //2.2 添加任務(wù)到隊(duì)列,并且會執(zhí)行
    dispatch_sync(q, task);
/**
 異步執(zhí)行任務(wù)  哥么如果任務(wù)沒有執(zhí)行完畢,可以不用等待,異步執(zhí)行下一個任務(wù) 
 具備開啟線程的能力!  異步通常又是多線程的代名詞!!
 */
-(void)gcdDemo2{
    //1.創(chuàng)建隊(duì)列
    dispatch_queue_t q = dispatch_get_global_queue(0, 0);
    //2 定義任務(wù) -- block
    void(^task)() = ^{
        NSLog(@"%@",[NSThread currentThread]);
    };
    //3. 添加任務(wù)到隊(duì)列
    dispatch_async(q, task);
}
//線程間通信-切換子線程到主線程更新UI
//指定任務(wù)執(zhí)行方法 -- 異步
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        //耗時操作
        NSLog(@"%@",[NSThread currentThread]);
        
        //更新UI 主隊(duì)列,就是專門負(fù)責(zé)在主線程上調(diào)度任務(wù)的隊(duì)列!
        //dispatch_get_main_queue  主隊(duì)列 住能操作主線程
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"更新UI%@",[NSThread currentThread]);
            
        });
        
    });
//MARK:串行隊(duì)列,同步任務(wù)
/**
*   不會開啟線程,會順序執(zhí)行
*/
-(void)gcdDemo1{
    //1.隊(duì)列 - 串行
    
    /**
     1."ios" 隊(duì)列名稱:
     2. NULL 隊(duì)列的屬性: DISPATCH_QUEUE_SERIAL 表示串行!
     */
    dispatch_queue_t q = dispatch_queue_create("ios", NULL);
    
    //2.同步執(zhí)行任務(wù)
    for (int i = 0; i < 10; i++) {
        dispatch_sync(q, ^{
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
}
//MARK: 串行隊(duì)列,異步任務(wù)
-(void)gcdDemo2{
    /**
     會開幾條線程?會順序執(zhí)行嗎?
     開一條線程,順序執(zhí)行
     */
    //1.隊(duì)列 - 串行
    dispatch_queue_t q = dispatch_queue_create("tanzhouios", NULL);
    
    //2.異步執(zhí)行任務(wù)
    for (int i = 0; i < 10; i++) {
        NSLog(@"%d------------",i);
        dispatch_async(q, ^{
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
    //哥么在主線程!
    NSLog(@"come here");
}
//MARK : 并發(fā)隊(duì)列,異步執(zhí)行
-(void)gcdDemo3{
    //1.隊(duì)列 - 并發(fā) DISPATCH_QUEUE_CONCURRENT
    dispatch_queue_t q = dispatch_queue_create("tanzhouios", DISPATCH_QUEUE_CONCURRENT);
    
    //2.異步執(zhí)行任務(wù)
    for (int i = 0; i < 10; i++) {
        dispatch_async(q, ^{
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
    //哥么在主線程!
    NSLog(@"come here");
}
//MARK : 并發(fā)隊(duì)列,同步執(zhí)行   和 串行隊(duì)列,同步執(zhí)行 效果一樣!
-(void)gcdDemo4{
    
    // 會開線程嗎?  順序執(zhí)行?  come here?
    //  不會          順序     最后
    
    //1.隊(duì)列 - 并發(fā) DISPATCH_QUEUE_CONCURRENT
    dispatch_queue_t q = dispatch_queue_create("tanzhouios", DISPATCH_QUEUE_CONCURRENT);
    
    //2.同步執(zhí)行任務(wù)
    for (int i = 0; i < 10; i++) {
        dispatch_sync(q, ^{
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
    //哥么在主線程!
    NSLog(@"come here");
}

小結(jié):
只有異步才會開啟子線程!同步不開啟!
開幾條線程,取決于隊(duì)列,串行開一條,并發(fā)可以開多條(異步)

個人理解鎖這個問題

線程鎖:是多條線程同時訪問一個資源時需要一個互斥鎖;
GDC-死鎖:主隊(duì)列是一個串行隊(duì)列;在主隊(duì)列里添加一個同步任務(wù)會造成死鎖;互相等待的局面;

    //主隊(duì)列是專門負(fù)責(zé)在主線程上調(diào)度任務(wù)的隊(duì)列 --> 不會開線程
    //1.隊(duì)列 --> 已啟動主線程,就可以獲取主隊(duì)列
    dispatch_queue_t q = dispatch_get_main_queue();
    
    //2.同步任務(wù)  ==> 死鎖
    //走到這里添加一個同步任務(wù),主隊(duì)列的任務(wù)是不是要等他執(zhí)行完了在執(zhí)行;
    dispatch_sync(q, ^{
        NSLog(@"能來嗎? ");
        //主隊(duì)列里的任務(wù)沒執(zhí)行完呢你想執(zhí)行這同步任務(wù),你是不是要等主隊(duì)列執(zhí)行完了才能執(zhí)行;
    });
    NSLog(@"come here");
死鎖

注意:
主隊(duì)列不是全局隊(duì)列
全局隊(duì)列:dispatch_get_global_queue
全局隊(duì)列本質(zhì)上是并發(fā)隊(duì)列
主隊(duì)列:dispatch_get_main_queue()
主隊(duì)列是一個串行隊(duì)列

主隊(duì)列是串行的 主隊(duì)列里的任務(wù)默認(rèn)只有一個(不手動添加的話) 這個任務(wù)是同步的 主隊(duì)列里直接添加一個異步任務(wù) 不開開啟子線程

主隊(duì)列只負(fù)責(zé)主線程

    //主隊(duì)列是專門負(fù)責(zé)在主線程上調(diào)度任務(wù)的隊(duì)列 --> 不會開線程
    
    //1.隊(duì)列 --> 一啟動主線程,就可以獲取主隊(duì)列
    dispatch_queue_t q = dispatch_get_main_queue();
    
    //2.異步任務(wù)
    dispatch_async(q, ^{
        NSLog(@"%@",[NSThread currentThread]);
    });
    NSLog(@"come here");
    //全局隊(duì)列
    /*  參數(shù)
     1. 涉及到系統(tǒng)適配
     iOS 8   服務(wù)質(zhì)量
     QOS_CLASS_USER_INTERACTIVE    用戶交互(希望線程快速被執(zhí)行,不要用好使的操作)
     QOS_CLASS_USER_INITIATED      用戶需要的(同樣不要使用耗時操作)
     QOS_CLASS_DEFAULT             默認(rèn)的(給系統(tǒng)來重置隊(duì)列的)
     QOS_CLASS_UTILITY             使用工具(用來做耗時操作)
     QOS_CLASS_BACKGROUND          后臺
     QOS_CLASS_UNSPECIFIED         沒有指定優(yōu)先級
     iOS 7  調(diào)度的優(yōu)先級
     - DISPATCH_QUEUE_PRIORITY_HIGH 2               高優(yōu)先級
     - DISPATCH_QUEUE_PRIORITY_DEFAULT 0            默認(rèn)優(yōu)先級
     - DISPATCH_QUEUE_PRIORITY_LOW (-2)             低優(yōu)先級
     - DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后臺優(yōu)先級
     
     提示:尤其不要選擇BACKGROUND 優(yōu)先級,服務(wù)質(zhì)量,線程執(zhí)行會慢到令人發(fā)指!!!
     
     
     2. 為未來使用的一個保留,現(xiàn)在始終給0.
     
     老項(xiàng)目中,一般還是沒有淘汰iOS 7  ,沒法使用服務(wù)質(zhì)量
     */
    dispatch_queue_t q = dispatch_get_global_queue(0, 0);
    //以第一個0用來設(shè)置優(yōu)先級
    //第二個0還沒有定義
    /*
     全局隊(duì)列 & 并發(fā)隊(duì)列   區(qū)別
     1> 名稱,并發(fā)隊(duì)列取名字,適合于企業(yè)開發(fā)跟蹤錯誤
     2> release,在MRC 并發(fā)隊(duì)列 需要使用的
        dispatch_release(q);//ARC 情況下不需要release !
     
     
     全局隊(duì)列 & 串行隊(duì)列
        全局隊(duì)列: 并發(fā),能夠調(diào)度多個線程,執(zhí)行效率高
            - 費(fèi)電
        串行隊(duì)列:一個一個執(zhí)行,執(zhí)行效率低
            - 省點(diǎn)
     
        判斷依據(jù):用戶上網(wǎng)方式
            - WIFI : 可以多開線程
            - 流量  : 盡量少開線程
     
     */
    //1.隊(duì)列
    dispatch_queue_t q = dispatch_queue_create("tanzhou", DISPATCH_QUEUE_CONCURRENT);
    //2.全局隊(duì)列
    dispatch_queue_t q = dispatch_get_global_queue(0, 0);

 延遲執(zhí)行
    /**
     從現(xiàn)在開始,進(jìn)過多少納秒之后,讓 queue隊(duì)列,調(diào)度 block 任務(wù),異步執(zhí)行!
     參數(shù):
     1.when
     2.queue
     3.block
     */
    dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.00003 * NSEC_PER_SEC));
    dispatch_after(when, dispatch_queue_create("tanzhou", NULL), ^{
        NSLog(@"%@",[NSThread currentThread]);
    });
GCD:執(zhí)行一次 常用于單利
    //蘋果提供的 一次執(zhí)行機(jī)制,不僅能夠保證一次執(zhí)行!而且是線程安全的!!
    static dispatch_once_t onceToken;
    NSLog(@"%ld",onceToken);
    //蘋果推薦使用 gcd 一次執(zhí)行,效率高
    //不要使用互斥鎖,效率低!
    dispatch_once(&onceToken, ^{
        //只會執(zhí)行一次!!
        NSLog(@"執(zhí)行了%@",[NSThread currentThread]);
    });
GCD調(diào)度組
 //1.隊(duì)列
    dispatch_queue_t q = dispatch_get_global_queue(0, 0);
    
    //2.調(diào)度組
    dispatch_group_t g = dispatch_group_create();
    
    //3.添加任務(wù),讓隊(duì)列調(diào)度,任務(wù)執(zhí)行情況,最后通知群組
    dispatch_group_async(g, q, ^{
        NSLog(@"download A%@",[NSThread currentThread]);
    });
    dispatch_group_async(g, q, ^{
        [NSThread sleepForTimeInterval:1.0];
        NSLog(@"download B%@",[NSThread currentThread]);
    });
    dispatch_group_async(g, q, ^{
        [NSThread sleepForTimeInterval:1.0];
        NSLog(@"download C%@",[NSThread currentThread]);
    });
    
    //4.所有任務(wù)執(zhí)行完畢后,通知
    //用一個調(diào)度組,可以監(jiān)聽全局隊(duì)列的任務(wù),主隊(duì)列去執(zhí)行最后的任務(wù)
    //dispatch_group_notify 本身也是異步的!
    dispatch_group_notify(g, dispatch_get_main_queue(), ^{
        //更新UI,通知用戶
        NSLog(@"OK %@",[NSThread currentThread]);
    });
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末栅哀,一起剝皮案震驚了整個濱河市震肮,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌留拾,老刑警劉巖戳晌,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異痴柔,居然都是意外死亡沦偎,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門咳蔚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豪嚎,“玉大人,你說我怎么就攤上這事谈火〕扪” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵糯耍,是天一觀的道長妄荔。 經(jīng)常有香客問我,道長谍肤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任哗伯,我火速辦了婚禮荒揣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘焊刹。我一直安慰自己系任,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布虐块。 她就那樣靜靜地躺著俩滥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贺奠。 梳的紋絲不亂的頭發(fā)上霜旧,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機(jī)與錄音儡率,去河邊找鬼挂据。 笑死,一個胖子當(dāng)著我的面吹牛儿普,可吹牛的內(nèi)容都是我干的崎逃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼眉孩,長吁一口氣:“原來是場噩夢啊……” “哼个绍!你這毒婦竟也來了勒葱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后舒裤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體铅檩,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年荣德,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡瓦阐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出篷牌,到底是詐尸還是另有隱情睡蟋,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布枷颊,位于F島的核電站戳杀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏夭苗。R本人自食惡果不足惜信卡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望题造。 院中可真熱鬧傍菇,春花似錦、人聲如沸界赔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽淮悼。三九已至咐低,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間袜腥,已是汗流浹背见擦。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瞧挤,地道東北人锡宋。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像特恬,于是被迫代替她去往敵國和親执俩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

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

  • 多線程 在iOS開發(fā)中為提高程序的運(yùn)行效率會將比較耗時的操作放在子線程中執(zhí)行癌刽,iOS系統(tǒng)進(jìn)程默認(rèn)啟動一個主線程役首,用...
    郭豪豪閱讀 2,597評論 0 4
  • 又來到了一個老生常談的問題尝丐,應(yīng)用層軟件開發(fā)的程序員要不要了解和深入學(xué)習(xí)操作系統(tǒng)呢? 今天就這個問題開始衡奥,來談?wù)劜?..
    tangsl閱讀 4,127評論 0 23
  • 歡迎大家指出文章中需要改正或者需要補(bǔ)充的地方爹袁,我會及時更新,非常感謝矮固。 一. 多線程基礎(chǔ) 1. 進(jìn)程 進(jìn)程是指在系...
    xx_cc閱讀 7,191評論 11 70
  • .一.進(jìn)程 進(jìn)程:是指在系統(tǒng)中正在運(yùn)行的一個應(yīng)用程序,每個進(jìn)程之間是獨(dú)立的失息,每個進(jìn)程均運(yùn)行在其專用且受保護(hù)的內(nèi)存空...
    IIronMan閱讀 4,486評論 1 33
  • 在情人節(jié)這天,已經(jīng)不再想著收什么禮物了档址,因?yàn)槔瞎珡膩頉]有送過禮物盹兢,不同的是,自己不再期盼不再少女心守伸。 今年的情人節(jié)...
    韋陀閱讀 216評論 0 1