日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

java线程主要状态及转换_Java线程状态转换及控制

發(fā)布時(shí)間:2025/4/5 java 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java线程主要状态及转换_Java线程状态转换及控制 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

線程的狀態(tài)(系統(tǒng)層面)

一個(gè)線程被創(chuàng)建后就進(jìn)入了線程的生命周期。在線程的生命周期中,共包括新建(New)、就緒(Runnable)、運(yùn)行(Running)、阻塞(Blocked)和死亡(Dead)這五種狀態(tài)。當(dāng)線程啟動(dòng)以后,CPU需要在多個(gè)線程之間切換,所以線程也會(huì)隨之在運(yùn)行、阻塞、就緒這幾種狀態(tài)之間切換。

線程的狀態(tài)轉(zhuǎn)換如圖:

當(dāng)一個(gè)正在運(yùn)行的線程遇到如下情況時(shí),線程會(huì)從運(yùn)行態(tài)轉(zhuǎn)為阻塞態(tài):

①?線程調(diào)用sleep、join等方法。

②?線程調(diào)用了一個(gè)阻塞式IO方法。

③?線程試圖獲得一個(gè)同步監(jiān)視器,但是該監(jiān)視器正在被其他線程持有。

④ 線程在等待某個(gè) notify 通知。

⑤ 程序調(diào)用了線程的suspend方法將該線程掛起。

當(dāng)線程被阻塞后,其他線程就有機(jī)會(huì)獲得CPU資源而被執(zhí)行。當(dāng)上述導(dǎo)致線程被阻塞的因素解除后,線程會(huì)回到就緒狀態(tài)等待處理機(jī)調(diào)度而被執(zhí)行。

當(dāng)一個(gè)線程執(zhí)行結(jié)束后,該線程進(jìn)入死亡狀態(tài)。

有以下3種方式可結(jié)束一個(gè)線程:

① run 方法執(zhí)行完畢。

② 線程拋出一個(gè)異常或錯(cuò)誤,而該異常或錯(cuò)誤未被捕獲。

③ 調(diào)用線程的 stop方法結(jié)束該線程。(不推薦使用)

線程的控制

Thread類中提供了一些控制線程的方法,通過(guò)這些方法可以輕松地控制一個(gè)線程的執(zhí)行和運(yùn)行狀態(tài),以達(dá)到程序的預(yù)期效果。

join 方法

如果線程A調(diào)用了線程B的join方法,線程A將被阻塞,等待線程B執(zhí)行完畢后線程A才會(huì)被執(zhí)行。這里需要注意一點(diǎn)的是,join方法必須在線程B的start方法調(diào)用之后調(diào)用才有意義。join方法的主要作用就是實(shí)現(xiàn)線程間的同步,它可以使線程之間的并行執(zhí)行變?yōu)榇袌?zhí)行。

join 方法有以下3種重載形式:

① join(): 等待被join的線程執(zhí)行完成。

② join(long millis): 等待被join 的線程的時(shí)間為 millis 毫秒,如果該線程在millis 毫秒內(nèi)未結(jié)束,則不再等待。

③ join(long millis,int nanos): 等待被join的線程的時(shí)間最長(zhǎng)為 millis 毫秒加上nanos微秒。

public class JoinThread extends Thread{

@Override

public void run() {

for (int i = 0; i < 20; i++) {

System.out.println(Thread.currentThread().getName() + "---" + i);

try {

Thread.sleep(500);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

public class TestThreadState {

public static void main(String[] args) {

// 創(chuàng)建要加入當(dāng)前線程的線程,并啟動(dòng)

JoinThread j1 = new JoinThread();

j1.start();

// 加入當(dāng)前線程,阻塞當(dāng)前線程,直到加入線程執(zhí)行完畢

try {

j1.join();

} catch (InterruptedException e1) {

// TODO Auto-generated catch block

e1.printStackTrace();

}

for (int i = 0; i < 20; i++) {

System.out.println(Thread.currentThread().getName());

try {

Thread.sleep(100);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

我們定義了一個(gè)JoinThread類,它繼承了Thread類,這是我們要加入的線程類。

在main方法中,我們創(chuàng)建了JoinThread線程,并把它加入到當(dāng)前線程(主線程)中,并沒(méi)有指定當(dāng)前線程等待的時(shí)間,所以會(huì)一直阻塞當(dāng)前線程,直到JoinThread線程的run方法執(zhí)行完畢,才會(huì)繼續(xù)執(zhí)行當(dāng)前線程。

sleep 方法

當(dāng)線程A調(diào)用了 sleep方法,則線程A將被阻塞,直到指定睡眠的時(shí)間到達(dá)后,線程A才會(huì)重新被喚起,進(jìn)入就緒狀態(tài)。

sleep方法有以下2種重載形式:

① sleep(long millis):讓當(dāng)前正在執(zhí)行的線程暫停millis毫秒,該線程進(jìn)入阻塞狀態(tài)。

② sleep(long mills,long nanos):讓當(dāng)前正在執(zhí)行的線程暫停 millis 毫秒加上 nanos微秒。

public class Test {

public static void main(String[] args) {

for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName() + "---" + i);

try {

Thread.sleep(1000); // 阻塞當(dāng)前線程1s

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

這段代碼中沒(méi)有創(chuàng)建其他線程,只有當(dāng)前線程存在,也就是執(zhí)行main函數(shù)的主線程。for循環(huán)中每打印一次線程名稱,主線程就會(huì)被sleep方法阻塞1s,然后進(jìn)入就緒狀態(tài),重新等待被調(diào)到,實(shí)現(xiàn)了線程的控制。

yield 方法

當(dāng)線程A調(diào)用了yield方法,它可以暫時(shí)放棄處理器,但是線程A不會(huì)被阻塞,而是進(jìn)入就緒狀態(tài)。

public class YieldThread extends Thread {

@Override

public void run() {

for (int i = 0; i < 10; i++) {

System.out.println(Thread.currentThread().getName() + "---" + i);

// 主動(dòng)放棄

Thread.yield();

}

}

}

我們自定義了一個(gè)線程類YieldThread,在run方法中定義了一個(gè)for循環(huán),for循環(huán)中每打印一次線程名稱,就會(huì)調(diào)用一下yield方法,主動(dòng)放棄CUP讓給其它有相同優(yōu)先級(jí)或更高優(yōu)先級(jí)的線程,自己進(jìn)入就緒狀態(tài),等待被CPU調(diào)度。

設(shè)置線程的優(yōu)先級(jí)

每個(gè)線程都有自己的優(yōu)先級(jí),默認(rèn)情況下線程的優(yōu)先級(jí)都與創(chuàng)建該線程的父線程的優(yōu)先級(jí)相回。同時(shí)Thread類提供了setPriority(int priority) 和getPriority()方法設(shè)置和返回指定線程的優(yōu)先級(jí)。參數(shù)priority是一個(gè)整型數(shù)據(jù),用以指定線程的優(yōu)先級(jí)。priority 的取值范圍是1-10,默認(rèn)值為5,也可以使用Thread類提供的三個(gè)靜態(tài)常量設(shè)置線程的優(yōu)先級(jí)。

① MAX_PRIORITY:最高優(yōu)先級(jí),其值為10。

② MIN_PRIORITY:最低優(yōu)先級(jí),其值為1。

③ NORM_PRIORITY:普通優(yōu)先級(jí),其值為5。

public class TestThreadPriority {

public static void main(String[] args) {

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

ThreadPriority p1 = new ThreadPriority();

p1.setName("p1");

ThreadPriority p2 = new ThreadPriority();

p2.setName("p2");

ThreadPriority p3 = new ThreadPriority();

p3.setName("p3");

p1.setPriority(1);

p3.setPriority(10);

p1.start();

p2.start();

p3.start();

}

}

我們創(chuàng)建了三個(gè)線程p1、p2、p3,設(shè)置了p1的優(yōu)先級(jí)為1,p3的優(yōu)先級(jí)為10,并沒(méi)有設(shè)置p2的,所以p2的優(yōu)先級(jí)默認(rèn)是5。優(yōu)先級(jí)越高,表示獲取cup的機(jī)會(huì)越多,注意此處說(shuō)的是機(jī)會(huì),所以高優(yōu)先級(jí)的線程并不是一定先于低優(yōu)先級(jí)的線程被CPU調(diào)度,只是機(jī)會(huì)更大而已。

sleep方法和wait方法的區(qū)別是什么?

sleep?方法是Thread類的一個(gè)靜態(tài)方法,其作用是使運(yùn)行中的線程暫時(shí)停止指定的毫秒數(shù),從而該線程進(jìn)入阻塞狀態(tài)并讓出處理器,將執(zhí)行的機(jī)會(huì)讓給其他線程。但是這個(gè)過(guò)程中監(jiān)控狀態(tài)始終保持,當(dāng)sleep的時(shí)間到了之后線程會(huì)自動(dòng)恢復(fù)。

wait 方法是Object類的方法,它是用來(lái)實(shí)現(xiàn)線程同步的。當(dāng)調(diào)用某個(gè)對(duì)象的wait方法后,當(dāng)前線程會(huì)被阻塞并釋放同步鎖,直到其他線程調(diào)用了該對(duì)象的?notify?方法或者?notifyAll?方法來(lái)喚醒該線程。所以?wait?方法和?notify(或notifyAll)應(yīng)當(dāng)成對(duì)出現(xiàn)以保證線程間的協(xié)調(diào)運(yùn)行。

sleep方法和yield方法的區(qū)別是什么?

① sleep方法暫停當(dāng)前線程后,會(huì)給其他線程執(zhí)行機(jī)會(huì)而不會(huì)考慮其他線程的優(yōu)先級(jí)。但是yield方法只會(huì)給優(yōu)先級(jí)相同或者優(yōu)先級(jí)更高的線程執(zhí)行機(jī)會(huì)。

② sleep方法執(zhí)行后線程會(huì)進(jìn)入阻塞狀態(tài),而執(zhí)行了yield方法后,當(dāng)前線程會(huì)進(jìn)入就緒狀態(tài)。

③ 由于sleep方法的聲明拋出了 InterruptedException 異常,所以在調(diào)用sleep方法時(shí)需要catch 該異常或拋出該異常,而yield 方法沒(méi)有聲明拋出異常。

④ sleep 方法比yield 方法具有更好的可移植性。

補(bǔ)充一下sleep、yield、join和wait的差異:

①?sleep、join、yield時(shí)并不釋放對(duì)象鎖資源,在wait操作時(shí)會(huì)釋放對(duì)象資源,wait在被notify/notifyAll喚醒時(shí),重新去搶奪獲取對(duì)象鎖資源。

②?sleep、join、yield可以在任何地方使用,而wait,notify,notifyAll只能在同步控制方法或者同步控制塊中使用。

③?調(diào)用wait會(huì)立即釋放鎖,進(jìn)入等待隊(duì)列,但是notify()不會(huì)立刻釋放sycronized(obj)中的對(duì)象鎖,必須要等notify()所在線程執(zhí)行完sycronized(obj)同步塊中的所有代碼才會(huì)釋放這把鎖,然后供等待的線程來(lái)?yè)寠Z對(duì)象鎖。

Java中為什么不建議使用stop和suspend方法終止線程?

在Java中可以使用stop 方法停止一個(gè)線程,使該線程進(jìn)入死亡狀態(tài)。但是使用這種方法結(jié)束一個(gè)線程是不安全的,在編寫程序時(shí)應(yīng)當(dāng)禁止使用這種方法。

之所以說(shuō)stop方法是線程不安全的,是因?yàn)橐坏┱{(diào)用了Thread.stop()方法,工作線程將拋出一個(gè)ThreadDeath的異常,這會(huì)導(dǎo)致run方法結(jié)束執(zhí)行,而且結(jié)束的點(diǎn)是不可控的,也就是說(shuō),它可能執(zhí)行到run方法的任何一個(gè)位置就突然終止了。同時(shí)它還會(huì)釋放掉該線程所持有的鎖,這樣其他因?yàn)檎?qǐng)求該鎖對(duì)象而被阻塞的線程就會(huì)獲得鎖對(duì)象而繼續(xù)執(zhí)行下去。一般情況下,加鎖的目的是保護(hù)數(shù)據(jù)的一致性,然而如果在調(diào)用Thread.stop()后線程立即終止,那么被保護(hù)數(shù)據(jù)就有可能出現(xiàn)不一致的情況(數(shù)據(jù)的狀態(tài)不可預(yù)知)。同時(shí),該線程所持有的鎖突然被釋放,其他線程獲得同步鎖后可以進(jìn)入臨界區(qū)使用這些被破壞的數(shù)據(jù),這將有可能導(dǎo)致一些很奇怪的應(yīng)用程序錯(cuò)誤發(fā)生,而且這種錯(cuò)誤非常難以debug.所以在這里再次重申,不要試圖用stop 方法結(jié)束一個(gè)線程。

suspend方法可以阻塞一個(gè)線程,然而該線程雖然被阻塞,但它仍然持有之前獲得的鎖,這樣其他任何線程都不能訪問(wèn)相同鎖對(duì)象保護(hù)的資源,除非被阻塞的線程被重新恢復(fù)。如果此時(shí)只有一個(gè)線程能夠恢復(fù)這個(gè)被suspend的線程,但前提是先要訪問(wèn)被該線程鎖定的臨界資源。這樣便產(chǎn)生了死鎖。所以在編寫程序時(shí),應(yīng)盡量避免使用suspend,如確實(shí)需要阻塞一個(gè)線程的運(yùn)行,最好使用wait方法,這樣既可以阻塞掉當(dāng)前正在執(zhí)行的線程,同時(shí)又使得該線程不至于陷入死鎖。

用一句話說(shuō)就是:stop方法是線程不安全的,可能產(chǎn)生不可預(yù)料的結(jié)果;suspend方法可能導(dǎo)致死鎖。

如何終止一個(gè)線程?

在Java?中不推薦使用stop方法和suspend方法終止一個(gè)線程,因?yàn)槟鞘遣话踩?#xff0c;那么要怎樣終止一個(gè)線程呢?

方法一:使用退出標(biāo)志

正常情況下,當(dāng)Thread?或?Runnable?類的run方法執(zhí)行完畢后該線程即可結(jié)束,但是有些情況下run方法可能永遠(yuǎn)都不會(huì)停止,例如,在服務(wù)端程序中使用線程監(jiān)聽(tīng)客戶端請(qǐng)求,或者執(zhí)行其他需要循環(huán)處理的任務(wù)。這時(shí)如果希望有機(jī)會(huì)終止該線程,可將執(zhí)行的任務(wù)放在一個(gè)循環(huán)中(例如?while循環(huán)),并設(shè)置一個(gè)boolean型的循環(huán)結(jié)束的標(biāo)志。如果想使?while?循環(huán)在某一特定條件下退出,就可以通過(guò)設(shè)置這個(gè)標(biāo)志為true或false?來(lái)控制?while?循環(huán)是否退出。這樣將線程結(jié)束的控制邏輯與線程本身邏輯結(jié)合在一起,可以保證線程安全可控地結(jié)束。

讓我們來(lái)看一看案例:

public class TestQuitSign {

// 退出標(biāo)志

public static volatile boolean quitFlag = false;

// 退出標(biāo)志:針對(duì)運(yùn)行時(shí)的線程

public static void main(String[] args) {

// 線程一:每隔一秒,打印一條信息,當(dāng)quitFlag為true時(shí)結(jié)束run方法。

new Thread() {

public void run() {

System.out.println("thread start...");

while (!quitFlag) {

try {

Thread.sleep(1000);

} catch (Exception e) {

}

System.out.println("thread running...");

}

System.out.println("thread end...");

}

}.start();

// 線程二:等待三秒,設(shè)置quitFlag為true,終止線程一。

new Thread() {

public void run() {

try {

Thread.sleep(3000);

} catch (Exception e) {

// TODO: handle exception

}

quitFlag = true;

}

}.start();

}

}

在上面這段程序中的main方法里創(chuàng)建了兩個(gè)線程,第一個(gè)線程的run方法中有一個(gè)while循環(huán),該循環(huán)通過(guò)boolean型變量quitFlag控制其是否結(jié)束。因?yàn)樽兞縬uitFlag的初始值為false,所以如果不修改該變量,第一個(gè)線程中的run方法將不會(huì)停止,也就是說(shuō),第一個(gè)線程將永遠(yuǎn)不會(huì)終止,并且每隔1s在屏幕上打印出一條字符串。第二個(gè)線程的作用是通過(guò)修改變量quitFlag來(lái)終止第一個(gè)線程。在第二個(gè)線程的run方法中首先將線程阻塞3s,然后將quitFlag置為true.因?yàn)樽兞縬uitFlag是同一進(jìn)程中兩個(gè)線程共享的變量,所以可以通過(guò)修改quitFlag的值來(lái)控制第一個(gè)線程的執(zhí)行。當(dāng)變量quitFlag被置為true,第一個(gè)線程的while循環(huán)就可以終止,所以run方法就能執(zhí)行完畢,從而安全退出第一個(gè)線程。

注意,boolean?型變量?quitFlag 被聲明為?volatile,volatile?會(huì)保證變量在一個(gè)線程中的每一步操作在另一個(gè)線程中都是可見(jiàn)的,所以這樣可以確保將?quitFlag 置為true?后可以安全退出第一個(gè)線程。

方法二:使用?interrupt方法

使用退出線程標(biāo)志的方法終止一個(gè)線程存在一定的局限性,主要的限制就是這種方法只對(duì)運(yùn)行中的線程起作用,如果該線程被阻塞(例如,調(diào)用了?Thread.join()方法或者Thread.sleep()方法等)而處于不可運(yùn)行的狀態(tài)時(shí),則退出線程標(biāo)志的方法將不會(huì)起作用。

在這種情況下,可以使用Thread?提供的?interrupt()方法終止一個(gè)線程。因?yàn)樵摲椒m然不會(huì)中斷一個(gè)正在運(yùn)行的線程,但是它可以使一個(gè)被阻塞的線程拋出一個(gè)中斷異常,從而使線程提前結(jié)束阻塞狀態(tài),然后通過(guò)catch塊捕獲該異常,從而安全地結(jié)束該線程。

我們來(lái)看看下面的例子:

public class TestInterrupt {

// Interrupt方法: 針對(duì)阻塞狀態(tài)的線程

public static void main(String[] args) throws InterruptedException{

// 創(chuàng)建線程

Thread thread = new Thread() {

public void run() {

System.out.println("thread start...");

try {

Thread.sleep(10000);

} catch (InterruptedException e) { // 捕獲中斷異常

e.printStackTrace();

}

System.out.println("thread end...");

}

};

// 啟動(dòng)線程

thread.start();

// 主線程等待1秒,拋出一個(gè)中斷信號(hào)

Thread.sleep(1000);

thread.interrupt();

}

}

在上面這段程序中的main方法里創(chuàng)建了一個(gè)線程,在該線程的?run?方法中調(diào)用?sleep?函數(shù)將該線程阻塞10s.然后調(diào)用Thread?類的?start?方法啟動(dòng)該線程,該線程剛剛被啟動(dòng)就進(jìn)入阻塞狀態(tài)。主線程等待1s后調(diào)用thread.interrupt()拋出一個(gè)中斷信號(hào),在run方法中的catch會(huì)正常捕獲到這個(gè)中斷信號(hào),這樣被阻塞的該線程就會(huì)提前退出阻塞狀態(tài),不需要等待10s線程thread 就會(huì)被提前終止。

上述方法主要針對(duì)當(dāng)前線程調(diào)用了Thread.join()或者 Thread.sleep()等方法而被阻塞時(shí)終止該線程。如果一個(gè)線程被I/O阻塞,則無(wú)法通過(guò)thread.interrupt()拋出一個(gè)中斷信號(hào)而離開(kāi)阻塞狀態(tài)。這時(shí)可推而廣之,觸發(fā)一個(gè)與當(dāng)前I/O0阻塞相關(guān)的異常,使其退出I/O阻塞,然后通過(guò)catch 塊捕獲該異常,從而安全地結(jié)束該線程。

線程的狀態(tài)(JVM層面)

我們?cè)谏厦嬗懻摰木€程狀態(tài)是從操作系統(tǒng)層面來(lái)看的,這樣看比較直觀,也容易理解,也是一個(gè)線程在操作系統(tǒng)中真實(shí)狀態(tài)的體現(xiàn)。下面我們來(lái)看看Java 中線程的狀態(tài)及轉(zhuǎn)換。

Java 線程狀態(tài)

在Java中線程的狀態(tài)有6種,我們來(lái)看一看JDK 1.8幫助文檔中的說(shuō)明:

我們可以看到幫助文檔中的最后一行,這些狀態(tài)是不反映任何操作系統(tǒng)線程狀態(tài)的JVM層面的狀態(tài)。我們來(lái)具體看一看這六種狀態(tài):

NEW:初始狀態(tài),線程被創(chuàng)建,但是還沒(méi)有調(diào)用 start 方法。

RUNNABLED:運(yùn)行狀態(tài),JAVA 線程把操作系統(tǒng)中的就緒和運(yùn)行兩種狀態(tài)統(tǒng)稱為“運(yùn)行狀態(tài)”。

BLOCKED:阻塞狀態(tài),表示線程進(jìn)入等待狀態(tài),也就是線程因?yàn)槟撤N原因放棄了 CPU 使用權(quán),阻塞也分為幾種情況 :

等待阻塞:運(yùn)行的線程執(zhí)行了?Thread.sleep?、wait()、?join()?等方法JVM 會(huì)把當(dāng)前線程設(shè)置為等待狀態(tài),當(dāng) sleep 結(jié)束、join 線程終止或者wait線程被喚醒后,該線程從等待狀態(tài)進(jìn)入到阻塞狀態(tài),重新?lián)屨兼i后進(jìn)行線程恢復(fù);

同步阻塞:運(yùn)行的線程在獲取對(duì)象的同步鎖時(shí),若該同步鎖被其他線程鎖占用了,那么jvm會(huì)把當(dāng)前的線程放入到鎖池中 ;

其他阻塞:發(fā)出了 I/O請(qǐng)求時(shí),JVM 會(huì)把當(dāng)前線程設(shè)置為阻塞狀態(tài),當(dāng) I/O處理完畢則線程恢復(fù);

WAITING:等待狀態(tài),沒(méi)有超時(shí)時(shí)間,要被其他線程喚醒或者有其它的中斷操作;

執(zhí)行 wait()

執(zhí)行 join()

執(zhí)行 LockSupport.park()

TIME_WAITING:超時(shí)等待狀態(tài),超時(shí)以后自動(dòng)返回;

執(zhí)行 sleep(long)

執(zhí)行 wait(long)、join(long)

執(zhí)行 LockSupport.parkNanos(long)、LockSupport.parkUntil(long)

TERMINATED:終止?fàn)顟B(tài),表示當(dāng)前線程執(zhí)行完畢 。

Java 線程狀態(tài)轉(zhuǎn)換

總結(jié)

操作系統(tǒng)層面:

有5個(gè)狀態(tài),分別是:New(新建)、Runnable(就緒)、Running(運(yùn)行)、Blocked(阻塞)、Dead(死亡)。

JVM層面:

有6個(gè)狀態(tài),分別是:NEW(新建)、RUNNABLE(運(yùn)行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(超時(shí)等待)、TERMINATED(終止)。

主要由這幾個(gè)方法來(lái)控制:sleep、join、yield、wait、notify以及notifyALL。

總結(jié)

以上是生活随笔為你收集整理的java线程主要状态及转换_Java线程状态转换及控制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。