<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          關(guān)于線程的那些事……

          共 2512字,需瀏覽 6分鐘

           ·

          2021-11-14 12:15

          前言

          從今天開始我們要再次重新學(xué)習(xí)多線程的相關(guān)內(nèi)容,至于為什么要學(xué)習(xí)多線程,原因很簡(jiǎn)單,java是一門流行的web端開發(fā)語(yǔ)言,而web應(yīng)用中有一個(gè)核心的要素就是效率,也就是快速響應(yīng)用戶的需求,但是隨著業(yè)務(wù)的不斷發(fā)展,業(yè)務(wù)環(huán)境的復(fù)雜化,單一流程的應(yīng)用很難滿足高效率的需求,所以多線程就有了用武之地。

          線程

          基本知識(shí)點(diǎn)

          什么是線程

          線程是進(jìn)程中獨(dú)立運(yùn)行的子任務(wù),也是程序運(yùn)行的最小單位。通常情況下,一個(gè)進(jìn)程可以包括多個(gè)線程。如果你有仔細(xì)觀察過(guò)電腦任務(wù)管理的詳細(xì)信息的話,你一定對(duì)下面這張圖片不陌生:

          從這張圖中我們可以看出計(jì)算機(jī)的進(jìn)程數(shù)、線程數(shù)等數(shù)據(jù),這里的線程數(shù)就包括java軟件運(yùn)行時(shí)的線程,另外,我們從這張圖還可以看出來(lái),線程數(shù)遠(yuǎn)遠(yuǎn)大于進(jìn)程數(shù),這也從側(cè)面佐證了一個(gè)進(jìn)程可以包含多個(gè)線程。

          串行與并行

          說(shuō)到多線程就避不過(guò)串行和并行的話題,串行就是程序的每一行代碼依次執(zhí)行,在大多數(shù)的場(chǎng)景下,后面執(zhí)行的代碼,要依托于前面代碼的執(zhí)行結(jié)果,或者說(shuō)是后面的代碼必須在前面的代碼執(zhí)行完成之后才能被執(zhí)行;而并行就是代碼直接沒(méi)有任何依賴關(guān)系,代碼與代碼之間也沒(méi)有任何的運(yùn)行順序,兩段代碼可以同時(shí)運(yùn)行,當(dāng)然,這樣說(shuō)雖然也不完全對(duì),但也算說(shuō)清楚了并行與串行的應(yīng)用場(chǎng)景。

          說(shuō)了這么多,下面我們說(shuō)一些干貨:

          • 串行就是我們常說(shuō)的單線程,必須按照指定的順序運(yùn)行,所以效率低下,但同時(shí)卻可以確保順序
          • 并行就是我們常說(shuō)的多線程,線程與線程之間的執(zhí)行是沒(méi)有順序可言的,所以會(huì)存在線程安全問(wèn)題,但是效率比較高

          舉一個(gè)很形象的例子來(lái)說(shuō)明并行和串行,假設(shè)你有十件事需要做,按照串行的方式的話,你必須得一件一件地做事,一件事沒(méi)有完成的時(shí)候,是不可以進(jìn)行下一件事的;按照并行邏輯的話,你可以同時(shí)做這十件事,只要你有時(shí)間,你就可以選擇任意一件事來(lái)做,當(dāng)然如果你要是會(huì)分身術(shù)的話,那就叫真并發(fā)運(yùn)行了(這就特別類似單核CPU和多核CPU,單核的時(shí)候只能來(lái)回切換以提高利用效率,多核的時(shí)候就真的可以同時(shí)運(yùn)行多個(gè)任務(wù))

          創(chuàng)建方式

          關(guān)于線程的創(chuàng)建方式有三種,一種是直接通過(guò)繼承Thread類的方式。

          Thread

          這也是最原始的創(chuàng)建方式:

          public?class?MyThread?extends?Thread?{
          ????@Override
          ????public?void?run()?{
          ????????System.out.println("run?方法開始執(zhí)行了");
          ????}

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

          這種方式的缺點(diǎn)很明顯,因?yàn)樵?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">java中,一個(gè)類只能繼承一個(gè)類,所以如果一個(gè)類已經(jīng)繼承了父類,它就再?zèng)]辦法通過(guò)繼承Thread來(lái)實(shí)現(xiàn)多線程了,于是就有了第二種方式——Runnable接口

          Runnable

          runnable接口就比Thread類要靈活的多,因?yàn)?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">java的接口是運(yùn)行多實(shí)現(xiàn)的,所以一個(gè)類實(shí)現(xiàn)了其他接口以后,依然可以實(shí)現(xiàn)Runnable接口:

          public?class?RunnableDemo?extends?Observable?implements?Runnable?{
          ????@Override
          ????public?void?run()?{
          ????????System.out.println("我是繼承了Thread,并實(shí)現(xiàn)了Runnable的類");
          ????}

          ????public?static?void?main(String[]?args)?{
          ????????new?Thread(new?RunnableDemo()).start();
          ????}
          }

          但是runnable本身是沒(méi)法靠自己?jiǎn)?dòng)的,它必須通過(guò)Thread或者線程池來(lái)啟動(dòng),如果直接調(diào)用run方法,也只能是像普通方法一樣執(zhí)行。

          雖然RunableThread要靈活,它也能實(shí)現(xiàn)我們絕大多數(shù)的應(yīng)用場(chǎng)景,但是在某些應(yīng)用場(chǎng)景下,它也顯得很無(wú)能為力,比如run方法需要返回值,這時(shí)候callable應(yīng)運(yùn)而生。

          Callable

          相比于ThreadRunnable,Callable就是小萌新,因?yàn)樗?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">JDK1.5才引入的,而前兩個(gè)是從JDK1.0就已經(jīng)存在了:

          由于比較萌新,所以Callable的運(yùn)行方式也比較特殊,只能通過(guò)線程池啟動(dòng):

          public?class?CallableDemo?implements?Callable<String>?{
          ????@Override
          ????public?String?call()?throws?Exception?{
          ????????return?"hello?callable";
          ????}

          ????public?static?void?main(String[]?args)?throws?ExecutionException,?InterruptedException?{
          ????????Future?submit?=?Executors.newSingleThreadExecutor().submit(new?CallableDemo());
          ????????String?s?=?submit.get();
          ????????System.out.println(s);
          ????}
          }

          結(jié)語(yǔ)

          單就線程的知識(shí)點(diǎn)來(lái)說(shuō),這塊還是比較簡(jiǎn)單的,大多都是一些基礎(chǔ)的概念,但還是要扎實(shí)理解其中的一些要點(diǎn),這里我們做一個(gè)簡(jiǎn)單的梳理:

          • 線程是程序運(yùn)行的最小單元
          • 線程可以理解為在進(jìn)程中獨(dú)立運(yùn)行的子任務(wù)
          • 一個(gè)進(jìn)程可以包含多個(gè)線程
          • 多線程的特點(diǎn)是在同一時(shí)間執(zhí)行多個(gè)任務(wù)
          • 多線程就是通過(guò)使用異步技術(shù),提高處理器的利用效率

          最后,希望各位小伙伴記住一句話:不要為了使用多線程而使用多線程,要結(jié)合實(shí)際業(yè)務(wù)場(chǎng)景分析。好了,今天就到這里吧,各位小伙伴,晚安吧!

          - END -


          瀏覽 36
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩做爱视频 | 国内免费av | 国产露脸91国语对白 | 青青草视频涩情 | 91操操操|