Java多線程(一)--線程的一些基本概念

這周趕項(xiàng)目允耿,暫停了一下微博梳玫。結(jié)果今天看到簡(jiǎn)書app的圖標(biāo)竟然有負(fù)罪感!趁著周末右犹,更新一波提澎。。念链。

從本文開始盼忌,我們開始分析一個(gè)新的Java的知識(shí)點(diǎn)--多線程。要研究這個(gè)掂墓,首先我們要知道谦纱,什么是線程。

線程的定義

進(jìn)程是指一個(gè)內(nèi)存中運(yùn)行的應(yīng)用程序君编,每個(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間跨嘉,擁有自己的數(shù)據(jù)和代碼。

線程是指進(jìn)程中的一個(gè)任務(wù)吃嘿,一個(gè)進(jìn)程中可以運(yùn)行多個(gè)線程祠乃。線程是屬于某個(gè)進(jìn)程,進(jìn)程中的多個(gè)線程共享此進(jìn)程的內(nèi)存兑燥。

拿手機(jī)舉個(gè)例子亮瓷,我們拿著手機(jī)可以一邊聽歌一邊看微信,此時(shí)降瞳,微信和聽歌軟件就構(gòu)成了多進(jìn)程嘱支。即同一時(shí)刻,有不同的進(jìn)程在工作挣饥。而多線程就是指在同一個(gè)程序中除师,同時(shí)執(zhí)行多個(gè)任務(wù),通常扔枫,每個(gè)任務(wù)稱為一個(gè)線程汛聚。線程跟進(jìn)程的區(qū)別是,每個(gè)進(jìn)程都有自己獨(dú)立的數(shù)據(jù)空間茧吊,而同一類的線程共享數(shù)據(jù)贞岭。多進(jìn)程是為了提高CPU的使用率,而多線程是為了提高應(yīng)用程序的使用率搓侄。

線程的狀態(tài)

線程的狀態(tài)如下:

image

線程的狀態(tài)分為五種:

新建狀態(tài):當(dāng)使用某種方式創(chuàng)建一個(gè)線程對(duì)象后瞄桨,該線程就是新建狀態(tài)

就緒狀態(tài):當(dāng)已創(chuàng)建的線程的start()方法被調(diào)用后,就進(jìn)入就緒狀態(tài)讶踪。這種狀態(tài)也叫做"可執(zhí)行狀態(tài)"芯侥。在這種狀態(tài)下,該線程隨時(shí)等待被CPU調(diào)度執(zhí)行(注意乳讥,這個(gè)時(shí)候不是立即執(zhí)行柱查,而是等待CPU的調(diào)度)。

可運(yùn)行狀態(tài):在Java虛擬機(jī)中執(zhí)行的線程處于此狀態(tài)云石。即線程取得CPU的權(quán)限唉工,開始執(zhí)行。線程只能從就緒狀態(tài)進(jìn)入運(yùn)行狀態(tài)汹忠。(在任何給定時(shí)刻淋硝,一個(gè)可運(yùn)行的線程可能正在運(yùn)行也可能沒有運(yùn)行)

阻塞狀態(tài):當(dāng)線程因?yàn)槟撤N關(guān)系,無法獲得CPU的使用權(quán)限時(shí)宽菜,就處于這種狀態(tài)谣膳。比如調(diào)用的wait()方法(等待)、有同步鎖(阻塞)及調(diào)用了sleep()方法(計(jì)時(shí)等待)等铅乡。

死亡狀態(tài):以退出的線程處于此狀態(tài)继谚。退出可能是線程執(zhí)行完畢,或者是發(fā)生了異常等阵幸。

當(dāng)一個(gè)線程開始運(yùn)行的時(shí)候花履,它并不是始終運(yùn)行的。因?yàn)镴ava中多線程是搶占式調(diào)度挚赊,即多個(gè)線程搶占時(shí)間片來執(zhí)行任務(wù)臭挽。當(dāng)一個(gè)線程的時(shí)間片用完后,它就會(huì)被系統(tǒng)剝奪其運(yùn)行權(quán)限咬腕,并與其他線程共同爭(zhēng)奪下一個(gè)時(shí)間片的使用權(quán)欢峰。

線程的創(chuàng)建

創(chuàng)建線程的方式有:繼承Thread類、實(shí)現(xiàn)Runnable接口及通過Callable和Future新建一個(gè)線程涨共。

繼承Thread類

創(chuàng)建的步驟為:

1纽帖、繼承Thread類

2、重寫run方法

3举反、實(shí)例化我們寫的Thread類的子類懊直,并調(diào)用start方法啟動(dòng)線程

具體代碼如下:

//繼承Thread類
public class MyThread extends Thread{

   //重寫run方法(線程的執(zhí)行部分)
   @Override
    public void run() {
       //自己的代碼邏輯
       ........
    }

}

public class Main{

    public static void main(String [] args){
    
        //實(shí)例化一個(gè)MyThread類的子類
        MyThread myThread = new MyThread();
        //調(diào)用start方法啟動(dòng)線程
        myThread.start();
        
    }

}

實(shí)現(xiàn)Runnable接口

創(chuàng)建步驟為:

1、定義一個(gè)類火鼻,實(shí)現(xiàn)Runnable接口室囊,重寫run方法雕崩;

2、創(chuàng)建一個(gè)Runnable的實(shí)現(xiàn)類的實(shí)例融撞,并以此為參數(shù)創(chuàng)建一個(gè)Thread類

3盼铁、調(diào)用Thread類的start方法,啟動(dòng)線程

還可以創(chuàng)建一個(gè)實(shí)現(xiàn)Runnable接口的匿名類尝偎,或者創(chuàng)建一個(gè)實(shí)現(xiàn)Runnable接口的Java Lambda表達(dá)式(JDK8之后)饶火。

具體代碼如下:

//定義一個(gè)類,實(shí)現(xiàn)Runnable接口
public class MyRunnable implements Runnable {

    //重寫run方法
    @Override
    public void run() {
        //自己的代碼邏輯
        .......
    }
}

public class Main{

    public static void main(String [] args){
    
        //實(shí)例化一個(gè)Runnable實(shí)現(xiàn)類的實(shí)例
        MyRunnable myRunnable = new MyRunnable();
        //以myRunnable為參數(shù)實(shí)例化一個(gè)Thread類
        Thread thread = new Thread(myRunnable);
        //調(diào)用start方法啟動(dòng)線程
        thread();
        
        /**
          *--------分割線------
          */
          //創(chuàng)建Runnable的匿名實(shí)現(xiàn)
          Runnable myRunnable =new Runnable(){
                public void run(){
                     //自己的代碼邏輯
                      .......                 
                      }
              }
             
          //Runnable的Lambda實(shí)現(xiàn)
          Runnable runnable =() -> { //自己的代碼邏輯};      
        
}

注意:

1致扯、使用"myThread.run();"時(shí)肤寝,run()方法并非是由剛創(chuàng)建的新線程執(zhí)行,而是被創(chuàng)建新線程的當(dāng)前線程所執(zhí)行了抖僵。想要讓創(chuàng)建的新線程執(zhí)行run()方法鲤看,必須調(diào)用新線程的start()方法。且start()方法不可以多次調(diào)用耍群。

2刨摩、調(diào)用start()方法后,并不是讓線程立刻執(zhí)行世吨,而是將線程變?yōu)榭蓤?zhí)行狀態(tài)澡刹,等待CPU的調(diào)度。

問題來了耘婚,當(dāng)用此方式創(chuàng)建線程后罢浇,線程執(zhí)行的run()方法是Runnable接口中的還是Thread類中的?

我們看一下Thread類的定義及其run()方法:

public class Thread implements Runnable {

private Runnable target;

public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
    
private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
       ......
        this.target = target;
       ......
    }

@Override
public void run() {
    if (target != null) {
        target.run();
     }
  }

}

可以看到沐祷,在run()方法中嚷闭,會(huì)判斷target是否為空,不為空則執(zhí)行Runnable的run()方法赖临,否則此方法不執(zhí)行任何操作并返回胞锰。也是因?yàn)槿绱耍琂ava提示Thread的子類要重寫此方法兢榨。

實(shí)現(xiàn)Runnable接口比繼承Thread類的優(yōu)勢(shì):

1嗅榕、避免了Java中的單繼承限制

2、適合多個(gè)相同的程序代碼的線程去處理同一個(gè)共享資源

3吵聪、代碼可以被多個(gè)線程共享且代碼和數(shù)據(jù)獨(dú)立凌那,增加了程序的健壯性

通過Callable和FutureTask

創(chuàng)建步驟為:

1、創(chuàng)建一個(gè)Callable接口的實(shí)現(xiàn)類吟逝,并實(shí)現(xiàn)call()方法

2帽蝶、使用FutureTask類包裝Callable實(shí)現(xiàn)類的對(duì)象,封裝了Callable的call()方法的返回值

3块攒、以FutureTask對(duì)象為Thread的參數(shù)創(chuàng)建線程励稳,并啟動(dòng)線程

4佃乘、調(diào)用FutureTask對(duì)象的get()方法,獲取線程執(zhí)行結(jié)束后的返回值

代碼如下:

//創(chuàng)建一個(gè)Callable接口的實(shí)現(xiàn)類驹尼,并實(shí)現(xiàn)call()方法
public class MyThread implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        //自己的代碼邏輯
        return value;
    }
}

public class Main{

    public static void main(String [] args){
    
        //使用FutureTask類包裝Callable實(shí)現(xiàn)類的對(duì)象
        MyThread myThread = new MyThread();

        FutureTask futureTask = new FutureTask<Integer>(myThread);

        //以FutureTask對(duì)象為Thread的參數(shù)創(chuàng)建線程
        Thread thread = new Thread(futureTask);

        thread.start();  
        
        //獲取值
        try {
            //get()方法會(huì)阻塞趣避,直到子線程執(zhí)行結(jié)束才返回
            int x = (int) futureTask.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }      
    }

}

其中,Callable的類型參數(shù)為返回值的類型扶欣,F(xiàn)uture保存異步計(jì)算的結(jié)果。

在計(jì)算過程中千扶,可以使用isDone方法判斷Future任務(wù)是否結(jié)束(包括正常結(jié)束或者中途退出)料祠,返回true表示完成,返回false表示未完成澎羞∷枵溃可以用cancal方法取消計(jì)算。

一般推薦使用實(shí)現(xiàn)Runable或Callable接口的方式來創(chuàng)建多線程妆绞。因?yàn)檫@樣既可以繼承其他類顺呕,而且多線程可以共享一個(gè)target,即多線程可以共同處理同一份資源括饶。

線程的優(yōu)先級(jí)及守護(hù)線程

線程優(yōu)先級(jí)

每個(gè)線程都有優(yōu)先級(jí)株茶,且默認(rèn)情況下赫编,線程繼承其父類的優(yōu)先級(jí)点弯。我們可以使用setPriority方法為線程設(shè)置優(yōu)先級(jí)「鸺遥可以將線程的優(yōu)先級(jí)設(shè)置在MIN_PRIORITY(1)和MAX_PRIORITY(10)之間技羔。NORM_PRIORITY表示線程優(yōu)先級(jí)為5僵闯,為默認(rèn)優(yōu)先級(jí)。數(shù)字越大藤滥,表示優(yōu)先級(jí)越高鳖粟。高優(yōu)先級(jí)的線程被CPU調(diào)用的概率大于低優(yōu)先級(jí)的線程。不過要注意的是線程優(yōu)先級(jí)無法保證線程的執(zhí)行順序拙绊,它是依賴于平臺(tái)的向图。比如在Linux下,線程優(yōu)先級(jí)僅適用于Java6之后标沪,在這之前線程優(yōu)先級(jí)沒有作用张漂。

守護(hù)線程

在Java中,線程可以分為用戶線程和守護(hù)線程谨娜,可以使用Thread類的setDaemon方法將一個(gè)線程設(shè)置為守護(hù)線程航攒。守護(hù)線程在后臺(tái)運(yùn)行,當(dāng)JVM中沒有其他非守護(hù)線程時(shí)趴梢,守護(hù)線程會(huì)和JVM一起結(jié)束漠畜。守護(hù)線程的作用是為其他線程提供服務(wù)币他,比如我們熟悉的GC就是這樣。要注意的是憔狞,不要用守護(hù)線程訪問文件或數(shù)據(jù)庫等資源蝴悉。因?yàn)槭刈o(hù)線程可能在任何時(shí)候發(fā)生中斷,而這個(gè)時(shí)候瘾敢,我們對(duì)資源文件的讀寫有可能還沒有完成拍冠。

有時(shí)候主線程都結(jié)束了,守護(hù)線程還在執(zhí)行簇抵,這是因?yàn)榫€程結(jié)束是需要時(shí)間的庆杜。

Thread類的部分方法

start()方法

start方法為將線程由新建狀態(tài)轉(zhuǎn)變?yōu)榭蛇\(yùn)行狀態(tài),其源碼如下:

//表示Java線程狀態(tài)的工具碟摆,初始化為線程未啟動(dòng)
private volatile int threadStatus = 0;

//線程是否運(yùn)行的標(biāo)志
boolean started = false;

//此線程的線程組
private ThreadGroup group;

public synchronized void start() {

        //判斷線程是否未啟動(dòng)或者已經(jīng)運(yùn)行晃财,滿足一項(xiàng)則拋出異常
        if (threadStatus != 0 || started)
            throw new IllegalThreadStateException();

        //添加次線程到其線程組
        group.add(this);
        
        //將運(yùn)行狀態(tài)置為false
        started = false;
        try {
              //調(diào)用本地方法啟動(dòng)線程
            nativeCreate(this, stackSize, daemon);
            //將線程的運(yùn)行狀態(tài)置為true
            started = true;
        } finally {
            try {
                   //如果啟動(dòng)失敗,從其線程組中移除此線程
                   //此線程組的狀態(tài)將回滾典蜕,就像從未嘗試啟動(dòng)線程一樣断盛。該線程再次被視為線程組的未啟動(dòng)成員,允許隨后嘗試啟動(dòng)該線程愉舔。
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                            }
        }
    }

可以看到钢猛,當(dāng)一個(gè)線程是未啟動(dòng)或者已運(yùn)行時(shí),調(diào)用start方法將拋出異常轩缤。當(dāng)線程啟動(dòng)失敗后厢洞,會(huì)將其從線程組中移除,以讓其有機(jī)會(huì)重新啟動(dòng)典奉。

sleep()方法

使當(dāng)前正在執(zhí)行的線程休眠(暫時(shí)停止執(zhí)行)躺翻,該線程不會(huì)失去任何監(jiān)視器的所有權(quán)。源碼如下:

private static final int NANOS_PER_MILLI = 1000000;

public static void sleep(long millis) throws InterruptedException {
     
        Thread.sleep(millis, 0);
    }

//實(shí)際調(diào)用的方法    
public static void sleep(long millis, int nanos)
    throws InterruptedException {
        //判斷傳入的毫秒和納秒是否有錯(cuò)誤
        if (millis < 0) {
            throw new IllegalArgumentException("millis < 0: " + millis);
        }
        if (nanos < 0) {
            throw new IllegalArgumentException("nanos < 0: " + nanos);
        }
        if (nanos > 999999) {
            throw new IllegalArgumentException("nanos > 999999: " + nanos);
        }
        //零睡眠
        if (millis == 0 && nanos == 0) {
            //如果線程為中斷狀態(tài)卫玖,則拋出異常并返回
            if (Thread.interrupted()) {
              throw new InterruptedException();
            }
            return;
        }
        //返回運(yùn)行的Java虛擬機(jī)的高分辨率時(shí)間源的當(dāng)前值公你,以納秒計(jì)。
        long start = System.nanoTime();
        //將傳入的時(shí)間轉(zhuǎn)為納秒級(jí)
        long duration = (millis * NANOS_PER_MILLI) + nanos;
         //獲取鎖
        Object lock = currentThread().lock;

        //等待可能會(huì)提前返回假瞬,所以循環(huán)直到睡眠時(shí)間結(jié)束陕靠。
        synchronized (lock) {
            while (true) {
                //調(diào)用本地方法
                sleep(lock, millis, nanos);

                long now = System.nanoTime();
                long elapsed = now - start;

                if (elapsed >= duration) {
                    break;
                }

                duration -= elapsed;
                start = now;
                millis = duration / NANOS_PER_MILLI;
                nanos = (int) (duration % NANOS_PER_MILLI);
            }
        }
    }

由上面的源碼可以看出,我們最終調(diào)用的是sleep(long millis, int nanos)方法脱茉。在sleep方法中剪芥,是通過循環(huán)不斷判斷當(dāng)前時(shí)間跟起始時(shí)間的差值,直到這個(gè)值大于等于我們傳入的休眠時(shí)間琴许,則線程可以繼續(xù)工作税肪。在此期間,當(dāng)前線程為阻塞狀態(tài)。

yield()方法

線程執(zhí)行此方法的作用是暫停當(dāng)前正在執(zhí)行的線程益兄,使其他具有相同優(yōu)先級(jí)的線程獲得運(yùn)行的機(jī)會(huì)锻梳。但是在實(shí)際中,我們不能保證其功能可以完全實(shí)現(xiàn)净捅,因?yàn)閥ield是將線程從運(yùn)行狀態(tài)變?yōu)榭蛇\(yùn)行狀態(tài)疑枯,在這種情況下,當(dāng)前線程可能會(huì)被CPU再次選中蛔六。此方法為本地方法荆永,jdk中源碼如下:

public static native void yield();

join()方法

此方法為讓一個(gè)線程加入到另一個(gè)線程的后面,在前面的線程沒有結(jié)束的時(shí)候国章,后面的線程不被執(zhí)行具钥。調(diào)用此方法會(huì)導(dǎo)致線程棧發(fā)生變化,當(dāng)然捉腥,這些變化都是瞬時(shí)的氓拼。

//負(fù)責(zé)此線程的join / sleep / park操作的同步對(duì)象
private final Object lock = new Object();

public final void join() throws InterruptedException {
        //調(diào)用join(long millis)方法
        join(0);
    }
    
public final void join(long millis, int nanos)
    throws InterruptedException {
        synchronized(lock) {
        //判斷傳入的參數(shù)是否正確
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }
        //根據(jù)條件判斷millis是否要加1
        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }
          //調(diào)用join(long millis)方法
        join(millis);
        }
    }
 
//真正被調(diào)用的方法    
public final void join(long millis) throws InterruptedException {
        synchronized(lock) {
        //返回當(dāng)前時(shí)間
        long base = System.currentTimeMillis();
        long now = 0;
          //判斷傳入的參數(shù)是否正確
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
          //以下就是根據(jù)isAlive(線程是否存活)你画,調(diào)用wait方法的循環(huán)
        if (millis == 0) {
            while (isAlive()) {
                lock.wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                lock.wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
        }
    }      

wait()方法的作用:導(dǎo)致當(dāng)前線程等待抵碟,直到另一個(gè)線程調(diào)用此對(duì)象的notify()方法或notifyAll()方法或指定的等待時(shí)間已經(jīng)過去。

由源碼可知坏匪,我們可以自己設(shè)置等待時(shí)間拟逮。但是如果我們不設(shè)置等待時(shí)間或者設(shè)置的等待時(shí)間為0,則線程會(huì)永遠(yuǎn)等待适滓。直到被其join的線程結(jié)束后敦迄,會(huì)調(diào)用this.notifyAll方法,使其結(jié)束等待凭迹。

未捕獲異常處理器

UncaughtExceptionHandler:是在Java Thread類中定義的罚屋,當(dāng)Thread由于未捕獲的異常而突然終止時(shí)調(diào)用的處理程序接口。這個(gè)接口只有一個(gè)方法:

//當(dāng)給定線程由于給定的未捕獲異常而終止時(shí)調(diào)用的方法嗅绸。Java虛擬機(jī)將忽略此方法拋出的任何異常
void uncaughtException(Thread t, Throwable e);

當(dāng)一個(gè)線程由于未捕獲的異常而即將終止時(shí)脾猛,Java虛擬機(jī)將使用getUncaughtExceptionHandler向線程查詢其UncaughtExceptionHandler并將調(diào)用處理程序的uncaughtException方法,將線程和異常作為參數(shù)傳遞鱼鸠。如果某個(gè)線程沒有顯式設(shè)置其UncaughtExceptionHandler猛拴,則其ThreadGroup對(duì)象將充當(dāng)其UncaughtExceptionHandler。如果ThreadGroup對(duì)象沒有處理異常的特殊要求蚀狰,它可以將調(diào)用轉(zhuǎn)發(fā)到getDefaultUncaughtExceptionHandler默認(rèn)的未捕獲異常處理程序愉昆。我們可以用setUncaughtExceptionHandler方法為任何線程設(shè)置一個(gè)處理器。也可以用Thread類的靜態(tài)方法setDefaultUncaughtExceptionHandler為所有線程設(shè)置一個(gè)默認(rèn)的處理器麻蹋。我們可以通過實(shí)現(xiàn)Thread.UncaughtExceptionHandler接口并重寫其uncaughtException方法來自定義一個(gè)未捕獲異常處理器跛溉。

小結(jié)

本文主要是簡(jiǎn)單的介紹一下線程的相關(guān)概念,使大家對(duì)線程有基本的了解。本文中涉及到的鎖及介紹的相關(guān)方法倒谷,會(huì)在后期的分析中一一講解蛛蒙。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市渤愁,隨后出現(xiàn)的幾起案子牵祟,更是在濱河造成了極大的恐慌,老刑警劉巖抖格,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诺苹,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡雹拄,警方通過查閱死者的電腦和手機(jī)收奔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滓玖,“玉大人坪哄,你說我怎么就攤上這事∈拼郏” “怎么了翩肌?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)禁悠。 經(jīng)常有香客問我念祭,道長(zhǎng),這世上最難降的妖魔是什么碍侦? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任粱坤,我火速辦了婚禮,結(jié)果婚禮上瓷产,老公的妹妹穿的比我還像新娘站玄。我一直安慰自己,他們只是感情好濒旦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布株旷。 她就那樣靜靜地躺著,像睡著了一般疤估。 火紅的嫁衣襯著肌膚如雪灾常。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天铃拇,我揣著相機(jī)與錄音钞瀑,去河邊找鬼。 笑死慷荔,一個(gè)胖子當(dāng)著我的面吹牛雕什,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼贷岸,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼壹士!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起偿警,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤躏救,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后螟蒸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盒使,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年七嫌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了少办。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡诵原,死狀恐怖英妓,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绍赛,我是刑警寧澤蔓纠,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站惹资,受9級(jí)特大地震影響贺纲,放射性物質(zhì)發(fā)生泄漏航闺。R本人自食惡果不足惜褪测,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望潦刃。 院中可真熱鬧侮措,春花似錦、人聲如沸乖杠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胧洒。三九已至畏吓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卫漫,已是汗流浹背菲饼。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留列赎,地道東北人宏悦。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親饼煞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子源葫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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

  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對(duì)應(yīng)一個(gè)進(jìn)程,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    勝浩_ae28閱讀 5,106評(píng)論 0 23
  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對(duì)應(yīng)一個(gè)進(jìn)程,當(dāng)一個(gè)程序進(jìn)入內(nèi)存運(yùn)行時(shí),即變成一個(gè)進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    小徐andorid閱讀 2,807評(píng)論 3 53
  • 單任務(wù) 單任務(wù)的特點(diǎn)是排隊(duì)執(zhí)行,也就是同步砖瞧,就像再cmd輸入一條命令后息堂,必須等待這條命令執(zhí)行完才可以執(zhí)行下一條命令...
    Steven1997閱讀 1,178評(píng)論 0 6
  • 前言 多線程并發(fā)編程是Java編程中重要的一塊內(nèi)容,也是面試重點(diǎn)覆蓋區(qū)域块促,所以學(xué)好多線程并發(fā)編程對(duì)我們來說極其重要...
    嘟爺MD閱讀 7,315評(píng)論 21 272
  • ??小感動(dòng) 1.慎思園的阿姨每次看見我都超開心储矩,我覺得像家人需要我不時(shí)回去看看~今天還非要送給我小橘子,覺得好溫暖...
    wutacooper閱讀 182評(píng)論 0 0