Android多進(jìn)程與多線程用例簡(jiǎn)介(線程篇)

進(jìn)程/線程分別是啥耕突?

  • 通俗地說(shuō)進(jìn)程和線程都是一個(gè)時(shí)間段的描述厂抽,是CPU工作時(shí)間段的描述。
  • 默認(rèn)情況下,同一應(yīng)用程序下的所有組件運(yùn)行在同一進(jìn)程中埠况。(每個(gè)應(yīng)用程序都有一個(gè)自己的進(jìn)程)
  • cpu的最小調(diào)度單位指的是線程(一個(gè)app最少有8個(gè)線程其中包括ui線程等)
  • cpu的最小資源分配單位是進(jìn)程

Android哪里用到了耸携?

  • 要說(shuō)哪里用到了?用到的地方還是很多的询枚!
  • 舉個(gè)例子:ui線程這個(gè)常聽(tīng)到的詞违帆,處理耗時(shí)任務(wù)需不需要在子線程處理?下載總不能放在主線程等著吧金蜀?總之呢在android上一切耗時(shí)的操作都是可以放在子線程中去做的畢竟5s 10s 20s 沒(méi)響應(yīng) Activity BroadcastReceiver Service就沒(méi)響應(yīng)Anr掉了哦刷后。

實(shí)現(xiàn)多線程的N種方式(包含信息交換)

其實(shí)實(shí)現(xiàn)線程切換的方式非常的多,最方便的還是當(dāng)屬rxjava但是rxjava的使用沒(méi)那么輕量級(jí)渊抄,我們總不能為了單純一個(gè)切換線程做一下查詢(xún)數(shù)據(jù)庫(kù)操作就去引入rxjava吧尝胆?我們不能為了更新個(gè)ui就引入rxjava吧?如果項(xiàng)目中已經(jīng)使用了rxjava并且熟悉rxjava這看起來(lái)還是很愜意的护桦,但是如果沒(méi)有呢含衔?這就很笨重了。

所以啰嗦了這么多主要想說(shuō)的還是下面這些種用法還是有必要學(xué)習(xí)的二庵!

Handler

  • handler原理就不闡述了贪染,有興趣的老哥可以看一下這篇簡(jiǎn)述
  • 咱說(shuō)說(shuō)用法吧

主線程和子線程通信(下面代碼使用了兩種方式一種是直接post(runnable)--看thread0,另一種是sendMessage(message)--看thread1

public class MainActivity extends ReactActivity {
Handler handler0 = new Handler();//主線程初始化Handler自動(dòng)綁定主線程
    Handler handler1 = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    textView.setText((String) msg.obj);
                    break;
            }
        }
    };
    TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        new TestThread0().start();
        new TestThread1().start();
    }
    class TestThread0 extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                Thread.sleep(5500);
                handler0.post(new Runnable() {
                    @Override
                    public void run() {
                        textView.setText("OK");
                    }
                });
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    class TestThread1 extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(5500);
                Message message = new Message();
                message.what = 001;
                message.obj = "OK";
                handler1.sendMessage(message);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

子線程和子線程通信
ps1:雙Thread形式

        new Thread() {
            @Override
            public void run() {
                //注意接受消息的線程一定要手動(dòng)開(kāi)啟Looper的循環(huán)催享,并且Looper要先準(zhǔn)備準(zhǔn)備完成后處理接收邏輯然后再開(kāi)啟循環(huán)杭隙。
                Looper.prepare();
                handler0 = new Handler() {
                    @Override
                    public void handleMessage(Message msg) {
                        switch (msg.what) {
                            case 1:
                                System.out.print((String) msg.obj);
                                break;
                        }
                    }
                };
                Looper.loop();
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 1;
                message.obj = "from thread1";
                handler0.sendMessage(message);

            }
        }.start();

ps2:使用ThreadHandler

HandlerThread handlerThread = new HandlerThread("handlerThread");
        handlerThread.start();
        final Handler handler = new Handler(handlerThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                //再handlerThread線程進(jìn)行處理
                switch (msg.what) {
                    case 1:
                        Log.d("test", "來(lái)自主線程的消息");
                        break;
                    case 2:
                        Log.d("test", "來(lái)自子線程的消息");
                        break;
                }
            }
        };
        handler.sendEmptyMessage(1);
        new Thread(new Runnable() {
            @Override
            public void run() {
                handler.sendEmptyMessage(2);
            }
        }).start();

AsyncTask

  • 其實(shí)AsyncTask的原理也不過(guò)就是handler+內(nèi)部維護(hù)的線程池進(jìn)行了一系列的封裝,它被設(shè)計(jì)出來(lái)的目的就是為了滿(mǎn)足Android的特殊需求:非主線程不能操作(UI)組件因妙,所以AsyncTask擴(kuò)展Thread增強(qiáng)了與主線程的交互的能力痰憎。如果你的應(yīng)用沒(méi)有與主線程交互,那么就直接使用Thread就好了攀涵。
  • 注意下面AsyncTask的泛形參數(shù)铣耘,他們有自己的意義
public abstract class AsyncTask<Params, Progress, Result>
//   第一個(gè)params代表了初始參數(shù)由主線程傳入
//   第二個(gè)Progress代表了執(zhí)行進(jìn)度的返回參數(shù)
//   第三個(gè)Result代表了執(zhí)行結(jié)果的返回參數(shù)
//   如果不需要某一項(xiàng)直接填void就可以咯,或者完全不填就代表了全部void
  • 使用的話看下面的代碼段吧
AsyncTask asyncTask = new AsyncTask() {
            @Override
            protected void onPreExecute() {
                //顧名思義PreExecute再execute之前意味著這個(gè)方法中可以更新UI以故,在耗時(shí)操作執(zhí)行之前的操作蜗细。
                super.onPreExecute();
            }
            @Override
            protected Object doInBackground(Object[] objects) {
                //這個(gè)是主要的方法,所有的耗時(shí)的操作需要在這個(gè)方法中處理怒详,
                publishProgress("");
                //調(diào)用publishProgress()方法來(lái)更新操作的進(jìn)度
                return null;
            }
            @Override
            protected void onProgressUpdate(Object[] values) {
                super.onProgressUpdate(values);
            }
            @Override
            protected void onPostExecute(Object o) {
                //在耗時(shí)操作完成之后鳄乏,觸發(fā)這個(gè)方法,在UI線程中執(zhí)行棘利,可以通知用戶(hù)操作已經(jīng)完成
                super.onPostExecute(o);
            }
        };
        asyncTask.execute();

IntentService

  • 要說(shuō)這個(gè)IntentService為啥放在了這個(gè)位置呢?因?yàn)檫@個(gè)東西別看它名字里面又有intent又有service它其實(shí)本質(zhì)上還是一個(gè)service朽缴,它繼承自service但是內(nèi)部維護(hù)了一個(gè)自己的線程這個(gè)線程是通過(guò)HandlerThread開(kāi)啟的(handlerThread本質(zhì)還是thread只是其內(nèi)部完成了Looper的初始化他還是要結(jié)合handler使用的)
  • 我們使用了IntentService最起碼有兩個(gè)好處,一方面不需要自己去newThread了;另一方面不需要考慮在什么時(shí)候關(guān)閉該Service了(源碼調(diào)用stopSelf(msg.arg1))善玫。
  • 下面我們看看這貨的基本使用吧
    首先注意IntentService使用的是啟動(dòng)方式開(kāi)啟service
    再次注意IntentService可以多次啟動(dòng),一但便會(huì)回掉再I(mǎi)ntentService的onHandleIntent方法,直到?jīng)]有需要處理的intent茅郎,該service會(huì)自己關(guān)閉蜗元。
    最后手動(dòng)關(guān)掉IntentService可以使用ondestory
 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent(MainActivity.this, MyIntentService.class);
        Bundle bundle = new Bundle();
        bundle.putString("1","one");
        startService(intent);
    }

    class MyIntentService extends IntentService {
        /**
         * Creates an IntentService.  Invoked by your subclass's constructor.
         *
         * @param name Used to name the worker thread, important only for debugging.
         */
        public MyIntentService(String name) {
            //此處可以做點(diǎn)準(zhǔn)備工作什么的
            super(name);
        }
        @Override
        protected void onHandleIntent(@Nullable Intent intent) {
            //此處已經(jīng)在IntentService開(kāi)啟的內(nèi)部線程處理了
            Log.d("IntentServiceTest", (String) intent.getExtras().get("1"));
            //此處怎么把處理好的消息返回給Ui線程呢??jī)煞N方法1:本地廣播2:handler(此處不述)
        }
    }

Thread(runnable/callable) + 線程池 + future/futuretask等

  • 開(kāi)啟線程的最簡(jiǎn)單方式Thread
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //方法一
        new Thread(new Runnable() {
            @Override
            public void run() {
                Log.d("ThreadTest", "方法一:我在子線程");
            }
        }).start();
        //方法二
        new myThread().start();
    }

    //方法二
    class myThread extends Thread {
        @Override
        public void run() {
            Log.d("ThreadTest", "方法二:我在子線程");
        }
    }

直接顯示創(chuàng)建線程是一種很不明智的做法系冗,由于在創(chuàng)建線程和銷(xiāo)毀線程上花的事件以及系統(tǒng)資源的開(kāi)銷(xiāo)很大奕扣,有可能造成大量同類(lèi)線程從而導(dǎo)致消耗完內(nèi)存或者“過(guò)度切換”的問(wèn)題,總之不要顯示創(chuàng)建線程掌敬,為了避險(xiǎn)這些問(wèn)題java給我們提供了線程池

  • 處理并發(fā)的最好方式線程池

最好不最好其實(shí)我也說(shuō)不準(zhǔn)惯豆,限于自己的姿勢(shì)水平目前處理多線程問(wèn)題都是適用線程池進(jìn)行管理的,而且Aaync內(nèi)部也是使用線程池管理了多個(gè)線程奔害,既然源碼都在用了楷兽,我想我們來(lái)使用它也不過(guò)分吧!
常用線程池

        ExecutorService executorService0 = Executors.newSingleThreadExecutor();
        //一個(gè)單線程化的線程池华临,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù)芯杀,保證所有任務(wù)按照指定順序(FIFO, LIFO, 優(yōu)先級(jí))執(zhí)行。(常用)
        ExecutorService executorService1 = Executors.newCachedThreadPool();
        //一個(gè)可緩存線程池雅潭,如果線程池長(zhǎng)度超過(guò)處理需要揭厚,可靈活回收空閑線程,若無(wú)可回收扶供,則新建線程筛圆。
        ExecutorService executorService2 = Executors.newFixedThreadPool(10);
        //一個(gè)定長(zhǎng)線程池,可控制線程最大并發(fā)數(shù)诚欠,超出的線程會(huì)在隊(duì)列中等待顽染。
        ExecutorService executorService3 = Executors.newWorkStealingPool();
        //創(chuàng)建持有足夠線程的線程池來(lái)支持給定的并行級(jí)別,并通過(guò)使用多個(gè)隊(duì)列轰绵,減少競(jìng)爭(zhēng)粉寞,它需要穿一個(gè)并行級(jí)別的參數(shù),如果不傳左腔,則被設(shè)定為默認(rèn)的CPU數(shù)量唧垦。
        ScheduledExecutorService executorService4 = Executors.newScheduledThreadPool(10);
        //一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行液样。(延遲執(zhí)行線程池)
        ScheduledExecutorService executorService5 = Executors.newSingleThreadScheduledExecutor();
        //創(chuàng)建一個(gè)單任務(wù)線程池振亮,支持定時(shí)及周期性任務(wù)執(zhí)行。(延遲執(zhí)行線程池)其實(shí)等于Executors.newScheduledThreadPool(1);
        

常規(guī)用法-延遲任務(wù)和循環(huán)任務(wù)

ScheduledExecutorService excutorService5 = Executors.newSingleThreadScheduledExecutor();
        excutorService5.schedule(new Runnable() {
            //延遲1s執(zhí)行
            @Override
            public void run() {
                Log.d("ScheduledTest", "test");
            }
        }, 1, TimeUnit.SECONDS);
        excutorService5.scheduleAtFixedRate(new Runnable() {
            //延遲3s執(zhí)行鞭莽,每隔1s進(jìn)行一次循環(huán)
            @Override
            public void run() {
                Log.d("ScheduledTest", "test1");
            }
        }, 3, 1, TimeUnit.SECONDS);
        excutorService5.shutdown();

常規(guī)用法

//不需要返回值的常規(guī)用法
ExecutorService executorService0 = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
            final int finalI = i;
            executorService0.execute(new Runnable() {
                @Override
                public void run() {
                    Log.d("executorTest", String.valueOf(finalI));
                }
            });
        }
executorService0.shutdown();

//需要返回值的常規(guī)用法
ExecutorService executorService0 = Executors.newSingleThreadExecutor();
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
            final int finalI = i;

            Future future = executorService1.submit(new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    System.out.print(String.valueOf(finalI));
                    return finalI;
                }
            });
            try {
                System.out.print(future.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
executorService0.shutdown();
for (int i = 0; i < 10; i++) {
            Future future1 = executorService1.submit(new Runnable() {
                @Override
                public void run() {

                }
            }, "always one");
            try {
                System.out.print(future1.get());
                //永遠(yuǎn)為“always one”這是因?yàn)閟ubmit方法指定了這個(gè)值坊秸。如若不指定返回null
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }

        }
executorService1.shutdown();

補(bǔ)充

提交任務(wù)的方式一般兩種submit()(有返回值)和execute()(沒(méi)返回值)在不需要一個(gè)結(jié)果的時(shí)候直接用execute()會(huì)提升很多性能。因?yàn)閟ubmit()方法內(nèi)部會(huì)封裝RunnableFuture(實(shí)際返回FutureTask的實(shí)例化)然后在交給execute()執(zhí)行澎怒,注意runnable調(diào)用submit()也會(huì)有返回值但是為值null褒搔。

關(guān)閉任務(wù)一般分為兩個(gè)階段第一階段shutdown調(diào)用后,不可以再submit新的task,已經(jīng)submit的將繼續(xù)執(zhí)行星瘾。第二階段shutdownNow試圖停止當(dāng)前正執(zhí)行的task走孽,并返回尚未執(zhí)行的task的list。

線程池理論上來(lái)講其實(shí)有無(wú)數(shù)種我們一般都是直接在Executors里面拿琳状,但是如果看過(guò)源碼我們發(fā)現(xiàn)其實(shí)它最終也是根據(jù)不同的需要實(shí)例化了ThreadPoolExecutor而已磕瓷。

future.get()是阻塞方法,如果調(diào)用這個(gè)方法來(lái)獲得返回值念逞,那么在獲得返回值之前當(dāng)前線程池都會(huì)阻塞在這個(gè)單線程上(部分并發(fā)線程池會(huì)出現(xiàn)問(wèn)題)困食。

FutureTask是啥?它就是Future這個(gè)接口的唯一實(shí)現(xiàn)類(lèi)(java的多態(tài)嘛肮柜!面向接口編程嘛陷舅!所以submit()方法返回的其實(shí)是FutureTask的實(shí)例化對(duì)象),內(nèi)部封裝了很多方法审洞,可以幫助判斷線程的執(zhí)行狀態(tài),并且還可以取消一個(gè)線程的執(zhí)行莱睁。

FutureTask的一個(gè)實(shí)用方法

ExecutorService executorService1 = Executors.newSingleThreadExecutor();
        FutureTask futureTask = new FutureTask(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("任務(wù)執(zhí)行中" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()));
                Thread.sleep(3000);
                Random random = new Random();
                return random.nextInt();
            }
        }) {
            @Override
            protected void done() {
                //此處是自定義FutureTask帶來(lái)的一個(gè)小福利,我們可以重寫(xiě)他的done方法在Callable或者runnable的call和run方法執(zhí)行完后會(huì)執(zhí)行這個(gè)call方法在此處我們可以做一些事件處理
                try {
                    int num = (int) this.get();

                    System.out.println("任務(wù)結(jié)束 結(jié)果是~~~~~~" + num + "~~~~~~" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }

                super.done();
            }
        };
        System.out.println("任務(wù)開(kāi)始" + new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()));
        executorService1.execute(futureTask);

線程同步問(wèn)題簡(jiǎn)略分析

  • 首先說(shuō)下synchronized關(guān)鍵字
/**
 *      一個(gè)單例模式的工具類(lèi)
 */

public class XXXTest {

    private static XXXTest instance;

    private static Object obj = new Object();

    private XXXTest(){}

    /**
     * synchronized 修飾的同步方法
     * */
    public static synchronized XXXTest getInstance(){
        if (instance == null){
            instance = new XXXTest();
        }
        return instance;
    }

    /**
     * 含有synchronized 同步快的方法
     * */
    public static XXXTest getInstance(){
        if (instance == null){
            synchronized (obj){
                instance = new XXXTest();
            }
        }
        return instance;
    }

}

以上是synchronized的兩種用法:
1芒澜、synchronized修飾方法仰剿,表示不同線程訪問(wèn)相同對(duì)象的相同方法,必須要排隊(duì)痴晦,相當(dāng)于synchronized對(duì)這個(gè)對(duì)象上了鎖南吮,只能獲取這個(gè)對(duì)象的鎖的線程才能使用這個(gè)方法,使用完畢自動(dòng)釋放鎖誊酌。
2部凑、synchronized修改某一段代碼,指定這段代碼塊要同步的對(duì)象進(jìn)行上鎖解鎖碧浊。例如例子中的代碼涂邀,先去判斷intance是否初始化,沒(méi)有就對(duì)obj進(jìn)行上鎖箱锐,防止創(chuàng)建多次比勉,破壞了單例模式。
兩種用法優(yōu)點(diǎn)缺點(diǎn)分析:
1驹止、synchronized修飾方法浩聋,使用簡(jiǎn)單,但是效率低下臊恋,不需要同步的操作也被迫同步衣洁。
2、synchronized代碼塊抖仅,使用相對(duì)復(fù)雜坊夫,需要對(duì)功能邏輯有完整的了解毙替,但是僅僅是同步了某一塊代碼,效率也大幅提升践樱。
注意:synchronized代碼塊指定同步對(duì)象不能為空對(duì)象

  • 再說(shuō)一下Thread自帶的wait()、notify()凸丸、notifyAll()方法

首先這幾個(gè)方法是Object類(lèi)提供的并不是Thread類(lèi)特有的拷邢,三個(gè)方法配套使用,wait() 使得線程進(jìn)入阻塞狀態(tài)屎慢,它有兩種形式瞭稼,一種允許 指定以毫秒為單位的一段時(shí)間作為參數(shù),另一種沒(méi)有參數(shù)腻惠,前者當(dāng)對(duì)應(yīng)的 notify() 被調(diào)用或者超出指定時(shí)間時(shí)線程重新進(jìn)入可執(zhí)行狀態(tài)环肘,后者則必須對(duì)應(yīng)的 notify() 被調(diào)用,notifyAll()則比較特殊它可以喚醒在此對(duì)象監(jiān)視器上等待的所有線程集灌。

作者簡(jiǎn)介:
就職于甜橙金融技術(shù)部悔雹,負(fù)責(zé)android開(kāi)發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末欣喧,一起剝皮案震驚了整個(gè)濱河市腌零,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌唆阿,老刑警劉巖益涧,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異驯鳖,居然都是意外死亡闲询,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)浅辙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)扭弧,“玉大人,你說(shuō)我怎么就攤上這事摔握〖睦牵” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵氨淌,是天一觀的道長(zhǎng)泊愧。 經(jīng)常有香客問(wèn)我,道長(zhǎng)盛正,這世上最難降的妖魔是什么删咱? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮豪筝,結(jié)果婚禮上痰滋,老公的妹妹穿的比我還像新娘摘能。我一直安慰自己,他們只是感情好敲街,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布团搞。 她就那樣靜靜地躺著,像睡著了一般多艇。 火紅的嫁衣襯著肌膚如雪逻恐。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 48,970評(píng)論 1 284
  • 那天峻黍,我揣著相機(jī)與錄音复隆,去河邊找鬼。 笑死姆涩,一個(gè)胖子當(dāng)著我的面吹牛挽拂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骨饿,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼亏栈,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了样刷?” 一聲冷哼從身側(cè)響起仑扑,我...
    開(kāi)封第一講書(shū)人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎置鼻,沒(méi)想到半個(gè)月后镇饮,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡箕母,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年储藐,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘶是。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钙勃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出聂喇,到底是詐尸還是另有隱情辖源,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布希太,位于F島的核電站克饶,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏誊辉。R本人自食惡果不足惜矾湃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堕澄。 院中可真熱鬧邀跃,春花似錦霉咨、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至僵驰,卻和暖如春棺滞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背矢渊。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留枉证,地道東北人矮男。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像室谚,于是被迫代替她去往敵國(guó)和親毡鉴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345

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

  • Java 多線程 線程和進(jìn)程的區(qū)別 線程和進(jìn)程的本質(zhì):由CPU進(jìn)行調(diào)度的并發(fā)式執(zhí)行任務(wù)秒赤,多個(gè)任務(wù)被快速輪換執(zhí)行猪瞬,使...
    安安zoe閱讀 2,190評(píng)論 1 18
  • Android中的線程 線程,在Android中是非常重要的入篮,主線程處理UI界面陈瘦,子線程處理耗時(shí)操作。如果在主線程...
    shenhuniurou閱讀 748評(píng)論 0 3
  • 第5章 多線程編程 5.1 線程基礎(chǔ) 5.1.1 如何創(chuàng)建線程 在java要?jiǎng)?chuàng)建線程潮售,一般有==兩種方式==:1)...
    AndroidMaster閱讀 1,786評(píng)論 0 11
  • 1.一鼓作氣痊项,再而衰,三而竭酥诽。爬山一定要一鼓作氣爬上去鞍泉,就算很累很累,也只能休息盡可能次數(shù)少時(shí)間短肮帐。不停地休息只會(huì)...
    酸酸酸酸酸奶閱讀 692評(píng)論 0 1
  • 話說(shuō)我的工位史咖驮,真是從繁到簡(jiǎn),曾經(jīng)我的工位都是凌亂不堪训枢,堆滿(mǎn)了各種文件書(shū)本托修,而現(xiàn)在的工位則是比較簡(jiǎn)單,這也見(jiàn)證了我...
    瀚文ILoveU閱讀 1,907評(píng)論 9 14