Java并發(fā)之線程

?????在前面我們介紹的一些內(nèi)容中锈死,我們的程序都是一條執(zhí)行流,一步一步的執(zhí)行穆壕。但其實(shí)這種程序?qū)ξ覀冇?jì)算機(jī)的資源的使用上是低效的待牵。例如:我們有一個(gè)用于計(jì)算的程序,主程序計(jì)算數(shù)據(jù)喇勋,在計(jì)算的過(guò)程中每得到一個(gè)結(jié)果就需要將其保存到外部磁盤上缨该,那么難道我們的主程序每次都要停止等待CPU將結(jié)果保存到磁盤之后,再繼續(xù)完成計(jì)算工作嗎茄蚯?要知道磁盤的速度可是巨慢的(相對(duì)內(nèi)存而言)压彭,我們?nèi)绻芊忠粋€(gè)線程去完成磁盤的寫(xiě)入工作睦优,主線程還是繼續(xù)計(jì)算的話,是不是效率更高了呢壮不?其實(shí)汗盘,并發(fā)就是這樣的一種思想,使用時(shí)間片分發(fā)給各個(gè)線程CPU的使用時(shí)間询一,給人感覺(jué)好像程序在同時(shí)做多個(gè)事情一樣隐孽,這樣做的好處主要在于它能夠?qū)ξ覀冋麄€(gè)的計(jì)算機(jī)資源有一個(gè)充分的利用,在多個(gè)線程競(jìng)爭(zhēng)計(jì)算機(jī)資源不沖突的前提下健蕊,充分的利用我們的資源菱阵。本篇文章首先來(lái)介紹并發(fā)的最基本的內(nèi)容-----線程。主要涉及以下一些內(nèi)容:

  • 定義線程的兩種不同的方法及它們之間的區(qū)別
  • 線程的幾種不同的狀態(tài)及其區(qū)別
  • Thread類中的一些線程屬性和方法
  • 多線程遇到的幾個(gè)典型的問(wèn)題

?????一缩功、創(chuàng)建一個(gè)線程
?????首先我們看創(chuàng)建一個(gè)線程的第一種方式晴及,繼承Thread類并重寫(xiě)其run方法。

public class MyThread extends Thread {
    @Override
    public void run(){
        System.out.println("this is mythread");
    }
}

現(xiàn)在我們來(lái)看看在主程序中如何啟動(dòng)我們自定義的線程:

public static void main(String[] args) {
    Thread myThread = new MyThread();
    myThread.start();
}

我們首先構(gòu)建一個(gè)Thread實(shí)例嫡锌,調(diào)用其start方法虑稼,調(diào)用該方法會(huì)為線程分配其所必須的堆棧資源,計(jì)數(shù)器势木,時(shí)間片等蛛倦,并在該方法的結(jié)束時(shí)刻調(diào)用我們重寫(xiě)的run方法,完成線程的啟動(dòng)啦桌。

但是在Java中類是單繼承的溯壶,也就是如果某個(gè)類已經(jīng)有了父類,那么它就不能被定義成線程類甫男。當(dāng)然且改,Java中也提供了第二種方法來(lái)定義一個(gè)線程類,這種方式實(shí)際上更加的接近本質(zhì)一些查剖。通過(guò)繼承接口Runnable并在其內(nèi)部重寫(xiě)一個(gè)run方法钾虐。

public class MyThread implements Runnable{
    @Override
    public void run(){
        System.out.println("this is mythread");
    }
}

啟動(dòng)線程的方式和上一種略微有點(diǎn)不同噪窘,但是本質(zhì)上都是一樣的笋庄。

public static void main(String[] args) {
        Thread myThread = new Thread(new MyThread());
        myThread.start();
    }

這里我們利用Thread的一個(gè)構(gòu)造函數(shù),傳入一個(gè)實(shí)現(xiàn)了Runnable接口的參數(shù)倔监。下面我們看看這個(gè)構(gòu)造函數(shù)的具體實(shí)現(xiàn):

public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

調(diào)用init方法對(duì)線程的一些狀態(tài)優(yōu)先級(jí)等做一個(gè)初始化的操作直砂,我們順便看看使用第一種方式創(chuàng)建線程實(shí)例的那個(gè)無(wú)參的構(gòu)造函數(shù):

public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }

可以看到,兩個(gè)構(gòu)造函數(shù)的內(nèi)部調(diào)用的是同一個(gè)方法浩习,只是傳入的參數(shù)不同而已静暂。所以他們之間的區(qū)別就在于初始化的時(shí)候這個(gè)Runnable參數(shù)是否為空,當(dāng)然這個(gè)參數(shù)的用處在run方法中也可以看出來(lái):

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

如果我們使用第二種方式構(gòu)建Thread實(shí)例谱秽,那么此處的target肯定不會(huì)是null洽蛀,自然會(huì)調(diào)用我們重寫(xiě)的run方法摹迷。如果使用的是第一種方式構(gòu)建的Thread實(shí)例,那么就不會(huì)調(diào)用上述的run方法郊供,而是調(diào)用的我們重寫(xiě)的Thread的run方法峡碉,所以從本質(zhì)上看,兩種方式的底層處理都是一樣的驮审。

這就是創(chuàng)建一個(gè)線程類并啟動(dòng)該線程的兩種不同的方式鲫寄,表面上略有不同,但是實(shí)際上都是一樣的調(diào)用init方法完成初始化疯淫。對(duì)于啟動(dòng)線程的start方法的源碼地来,由于調(diào)用本地native方法,暫時(shí)并不易解釋熙掺,有興趣的可以使用jvm指令查看本地方法的實(shí)現(xiàn)以了解整個(gè)線程從分配資源到調(diào)用run方法啟動(dòng)的全過(guò)程未斑。

?????二、線程的多種狀態(tài)
?????線程是有狀態(tài)的币绩,它會(huì)因?yàn)榈貌坏芥i而阻塞處于BLOCKED狀態(tài)颂碧,會(huì)因?yàn)闂l件不足而等待處于WAITING狀態(tài)等。Thread中有一個(gè)枚舉類型囊括了所有的線程狀態(tài):

public enum State {
  NEW,
  RUNNABLE,
  BLOCKED,
  WAITING,
  TIMED_WAITING,
  TERMINATED;
}

NEW狀態(tài)表示線程剛剛被定義类浪,還未實(shí)際獲得資源以啟動(dòng)载城,也就是還未調(diào)用start方法。

RUNNABLE表示線程當(dāng)前處于運(yùn)行狀態(tài)费就,當(dāng)然也有可能由于時(shí)間片使用完了而等待CPU重新的調(diào)度诉瓦。

BLOCKED表示線程在競(jìng)爭(zhēng)某個(gè)鎖失敗時(shí)被置于阻塞狀態(tài)

WAITING和TIMED_WAITING表示線程在運(yùn)行中由于缺少某個(gè)條件而不得不被置于條件等待隊(duì)列等待需要的條件或資源。

TERMINATED表示線程運(yùn)行結(jié)束力细,當(dāng)線程的run方法結(jié)束之后睬澡,該線程就會(huì)是TERMINATED狀態(tài)。

我們可以調(diào)用Thread的getState方法返回當(dāng)前線程的狀態(tài):

/*定義一個(gè)線程類*/
public class MyThread implements Runnable{
    @Override
    public void run(){
        System.out.println("myThread's state is : "+Thread.currentThread().getState());
    }
}
/*啟動(dòng)線程*/
public static void main(String[] args) throws InterruptedException {
        Thread myThread = new Thread(new MyThread());
        myThread.start();
        Thread.sleep(1000);
        System.out.println("myThread's state is : "+myThread.getState());
    }
這里寫(xiě)圖片描述

我們兩次輸出myThread線程的當(dāng)前狀態(tài)眠蚂,在run方法中輸出結(jié)果顯示該線程狀態(tài)為RUNNABLE煞聪,當(dāng)該run方法執(zhí)行結(jié)束時(shí)候,我們又一次輸出該線程的當(dāng)前狀態(tài)逝慧,結(jié)果顯示該線程處于TERMINATED昔脯。至于更加復(fù)雜的線程狀態(tài),我們將在后續(xù)的文章中逐漸進(jìn)行介紹笛臣。

?????三云稚、Thread類中的其他一些常用屬性及方法
?????以上我們介紹了創(chuàng)建線程的兩種不同的方式以及線程的幾種不同狀態(tài),有關(guān)于線程信息屬性的一些方法還沒(méi)有介紹沈堡。本小節(jié)將來(lái)簡(jiǎn)單介紹下線程所具有的基本的一些屬性以及一些常用的方法静陈。

首先每個(gè)線程都有一個(gè)id和一個(gè)name屬性,id是一個(gè)遞增的整數(shù),每創(chuàng)建一個(gè)線程該id就會(huì)加一拐格,該id的初始值是10,每創(chuàng)建一個(gè)線程就會(huì)往上加一刑赶。所以該id也間接的告訴了我們當(dāng)前線程在所有線程中的位置禁荒。name屬性往往是以“Thread-”+編號(hào)作為某個(gè)具體線程的name值。例如:

public static void main(String[] args){
        for (int i=0;i<10;i++){
            Thread myThread = new Thread(new MyThread());
            myThread.start();
            System.out.println(myThread.getName());
        }
    }

輸出結(jié)果:

這里寫(xiě)圖片描述

除此之外角撞,Thread中還有一個(gè)屬性daemon呛伴,它是一個(gè)boolean類型的變量,該變量指示了當(dāng)前線程是否是一個(gè)守護(hù)線程谒所。守護(hù)線程主要用于輔助主線程完成工作热康,如果主線程執(zhí)行結(jié)束,那么它的守護(hù)線程也會(huì)跟著結(jié)束劣领。例如:我們的main程序在執(zhí)行的時(shí)候姐军,始終有一個(gè)垃圾回收線程作為守護(hù)線程輔助一些對(duì)象的回收工作,當(dāng)main程序執(zhí)行結(jié)束時(shí)尖淘,守護(hù)線程也將退出內(nèi)存奕锌。關(guān)于守護(hù)線程有幾個(gè)方法:

public final boolean isDaemon() :判斷當(dāng)前線程是否是守護(hù)線程

public final void setDaemon(boolean on):設(shè)置當(dāng)前線程是否作為守護(hù)線程

還有一個(gè)方法較為常見(jiàn),join村生。該方法可以讓一個(gè)線程等待另一個(gè)線程執(zhí)行結(jié)束之后再繼續(xù)工作惊暴。例如:

public class MyThread implements Runnable{
    @Override
    public void run(){
        System.out.println("myThread is running");
    }
}
public static void main(String[] args) {
        Thread myThread = new Thread(new MyThread());
        myThread.start();

        //主線程等待myThread線程執(zhí)行結(jié)束
        myThread.join();

        System.out.println("waiting myThread done....");
    }

輸出結(jié)果:

這里寫(xiě)圖片描述

有人可能會(huì)疑問(wèn),我們使用多線程不就是為了充分利用計(jì)算機(jī)資源趁桃,使其同時(shí)執(zhí)行多個(gè)任務(wù)辽话,為什么又要讓一個(gè)線程等待另一個(gè)線程呢?其實(shí)某些時(shí)候卫病,主線程需要拿到所有分支線程計(jì)算的結(jié)果再一次進(jìn)行計(jì)算油啤,各個(gè)分支線程的進(jìn)度各有快慢,主線程唯有等待他們?nèi)繄?zhí)行結(jié)束之后才能繼續(xù)蟀苛。此時(shí)就需要使用join方法了益咬,所以說(shuō)每一個(gè)方法的存在都有其可應(yīng)用的場(chǎng)景。至于這個(gè)join的源代碼也是很有研究?jī)r(jià)值的帜平,我們將在后續(xù)的文章中對(duì)其源代碼的實(shí)現(xiàn)進(jìn)行進(jìn)一步的學(xué)習(xí)幽告。

還有一些屬性和方法,限于篇幅罕模,本文不再繼續(xù)學(xué)習(xí)评腺,大家可以自行查看源碼進(jìn)行學(xué)習(xí)帘瞭。下面我們看看多線程之后可能會(huì)遇到的幾個(gè)經(jīng)典的問(wèn)題淑掌。

?????四、多線程遇到的幾個(gè)典型的問(wèn)題
?????第一個(gè)可能遇到的問(wèn)題是蝶念,競(jìng)態(tài)條件抛腕。也就是說(shuō)芋绸,當(dāng)多個(gè)線程同時(shí)訪問(wèn)操作同一個(gè)對(duì)象的時(shí)候,最終的結(jié)果可能正確也可能不正確担敌,具體的執(zhí)行情況和線程實(shí)際的執(zhí)行時(shí)序有關(guān)摔敛。
例如:

/*我們定義一個(gè)線程*/
public class MyThread implements Runnable{
    public static int count;

    @Override
    public void run(){
        try {
            Thread.currentThread().sleep((int)(Math.random()*100));
            count++;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
/*main方法中啟動(dòng)多個(gè)線程*/
public static void main(String[] args){

        Thread[] threads = new Thread[100];
        for (int i=0;i<100;i++){
            threads[i] = new Thread(new MyThread());
            threads[i].start();
        }

        for (int j =0;j<100;j++){
            threads[j].join();
        }

        System.out.println(MyThread.count);
    }

首先在我們自定義的線程類中,有一個(gè)static公共變量全封,而我們的run方法主要就做兩個(gè)事情马昙,隨機(jī)睡一會(huì)和count增一。再來(lái)看main函數(shù)刹悴,首先定義了一百個(gè)線程并逐個(gè)啟動(dòng)行楞,然后主線程等待所有的子線程完成之后輸出count的值。

按照我們一般的思維土匀,這一百個(gè)線程子房,每個(gè)線程都是為count加一,最后的輸出結(jié)果應(yīng)該是100才對(duì)就轧。但是實(shí)際上我們多次運(yùn)行該程序得到的結(jié)果都是不一樣的证杭,但幾乎都是小于100的。

這里寫(xiě)圖片描述

這里寫(xiě)圖片描述

這里寫(xiě)圖片描述

為什么會(huì)出現(xiàn)這樣的情況呢妒御?主要原因還是在于為count加一這個(gè)操作解愤,它并非是原子操作,也就是說(shuō)想要為count加一需要經(jīng)過(guò)起碼兩個(gè)步驟:

  • 取count的當(dāng)前值
  • 為count加一

因?yàn)槊總€(gè)線程都是隨機(jī)睡了一會(huì)乎莉,有可能兩個(gè)線程同時(shí)醒來(lái)琢歇,都獲取到當(dāng)前的count的值,又同時(shí)為其加一梦鉴,這樣就導(dǎo)致兩個(gè)不同的線程卻只為count增加了一次值李茫。這種情況在多線程的前提下,發(fā)生的概率就更大了肥橙,所以這也是為什么我們得到的結(jié)果始終小于100但又每次都不同的原因魄宏。

第二個(gè)問(wèn)題是,內(nèi)存的可見(jiàn)性問(wèn)題存筏。就是說(shuō)宠互,如果兩個(gè)線程共享了同一個(gè)參數(shù),其中一個(gè)線程對(duì)共享參數(shù)的修改而另一個(gè)線程并不會(huì)立馬能夠看到椭坚。原因是這些修改會(huì)被暫存在CPU緩存中予跌,而沒(méi)有立馬寫(xiě)回內(nèi)存。例如:

public class MyThread extends Thread{
    public static boolean flag = false;

    @Override
    public void run(){
        while(!flag){
            //just running
        }
        System.out.println("my thread has finished ");
    }
}
public static void main(String[] args) throws InterruptedException {
        Thread myThread = new MyThread();
        myThread.start();

        Thread.sleep(1000);
        MyThread.flag = true;
        System.out.println("main thread has finished");
    }

首先我們定義一個(gè)線程類善茎,該線程類中有一個(gè)靜態(tài)共享變量flag券册,run方法做的事情很簡(jiǎn)單,死循環(huán)的做一些事情,等待外部線程更改flag的值烁焙,使其退出循環(huán)航邢。而main方法首先啟動(dòng)一個(gè)線程,然后修改共享變量flag的值骄蝇,按照常理線程myThread在main線程修改flag變量的值之后將退出循環(huán)膳殷,打印退出信息。但是實(shí)際的輸出結(jié)果為:

這里寫(xiě)圖片描述

main線程已經(jīng)結(jié)束了九火,而整個(gè)程序并沒(méi)有結(jié)束赚窃,線程myThread的結(jié)束信息也沒(méi)有被打印,這就說(shuō)明myThread線程還困在while循環(huán)中岔激,但是實(shí)際上主線程已經(jīng)將flag的值修改了考榨,只是myThread無(wú)法看見(jiàn)。這是什么原因呢鹦倚?

我們知道河质,每個(gè)線程都有一些緩存,往往為了效率震叙,對(duì)一個(gè)變量值的修改并不會(huì)立馬寫(xiě)會(huì)內(nèi)存掀鹅,而是注入緩存中,等到一定的時(shí)候才寫(xiě)回內(nèi)存媒楼,而當(dāng)別的線程來(lái)修改這些共享的變量的時(shí)候乐尊,他們是從內(nèi)存進(jìn)行讀取的,修改后可能也沒(méi)有及時(shí)的寫(xiě)回內(nèi)存中划址,這就很容易導(dǎo)致其他線程根本就看不到你所做的修改扔嵌。這就是典型的內(nèi)存可見(jiàn)性問(wèn)題。

本小節(jié)簡(jiǎn)單的介紹了多線程的兩個(gè)典型的問(wèn)題夺颤,解決辦法其實(shí)有多種痢缎,我們將在下篇文章中涉及。

以上的本篇內(nèi)容主要介紹了線程的基本概念世澜,如何創(chuàng)建一個(gè)線程独旷,如何啟動(dòng)一個(gè)線程,還有與線程相關(guān)的一些基本的屬性和方法寥裂,總結(jié)不到之處嵌洼,望大家指出,相互學(xué)習(xí)封恰。下篇文章將介紹一個(gè)用于解決多線程并發(fā)問(wèn)題的關(guān)鍵字synchronized麻养。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诺舔,隨后出現(xiàn)的幾起案子鳖昌,更是在濱河造成了極大的恐慌备畦,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遗遵,死亡現(xiàn)場(chǎng)離奇詭異萍恕,居然都是意外死亡逸嘀,警方通過(guò)查閱死者的電腦和手機(jī)车要,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)崭倘,“玉大人翼岁,你說(shuō)我怎么就攤上這事∷竟猓” “怎么了琅坡?”我有些...
    開(kāi)封第一講書(shū)人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)残家。 經(jīng)常有香客問(wèn)我榆俺,道長(zhǎng),這世上最難降的妖魔是什么坞淮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任茴晋,我火速辦了婚禮,結(jié)果婚禮上回窘,老公的妹妹穿的比我還像新娘诺擅。我一直安慰自己,他們只是感情好啡直,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布烁涌。 她就那樣靜靜地躺著,像睡著了一般酒觅。 火紅的嫁衣襯著肌膚如雪撮执。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,365評(píng)論 1 302
  • 那天舷丹,我揣著相機(jī)與錄音二打,去河邊找鬼。 笑死掂榔,一個(gè)胖子當(dāng)著我的面吹牛继效,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播装获,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼瑞信,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了穴豫?” 一聲冷哼從身側(cè)響起凡简,我...
    開(kāi)封第一講書(shū)人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤逼友,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后秤涩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體帜乞,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年筐眷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了黎烈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匀谣,死狀恐怖照棋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情武翎,我是刑警寧澤烈炭,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站宝恶,受9級(jí)特大地震影響符隙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜垫毙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一霹疫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧露久,春花似錦更米、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至消请,卻和暖如春栏笆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背臊泰。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工蛉加, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人缸逃。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓针饥,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親需频。 傳聞我的和親對(duì)象是個(gè)殘疾皇子丁眼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

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

  • 本文主要講了java中多線程的使用方法、線程同步昭殉、線程數(shù)據(jù)傳遞苞七、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法藐守、概述等。 首先講...
    李欣陽(yáng)閱讀 2,454評(píng)論 1 15
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,957評(píng)論 1 18
  • 前面的幾篇文章主要介紹了線程的一些最基本的概念蹂风,包括線程的間的沖突及其解決辦法卢厂,以及線程間的協(xié)作機(jī)制。本篇主要來(lái)學(xué)...
    Single_YAM閱讀 478評(píng)論 0 3
  • 未有過(guò)的壓郁 總是在不知不覺(jué)間淪陷 不知是我太過(guò)于煽情還是現(xiàn)實(shí)真的總是會(huì)讓人感觸良多 或許 在一個(gè)壓郁...
    小丑模樣閱讀 201評(píng)論 0 0
  • 介紹對(duì)象惠啄,剛剛接到了之前鄰居家的電話慎恒,說(shuō)給我介紹對(duì)象,其實(shí)吧我內(nèi)心很拒絕礁阁,但是還是要禮貌啊巧号,畢竟鄰居還是看得上我族奢,...
    啊貴閱讀 191評(píng)論 0 0