<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 為什么要多線程 為什么要多線程啊?操作系統有多進程管理,那多線程感覺沒有必要。 所謂線程,是程序代碼的執行,一個進程至少得一個線程,不然進程如何執行。 比如說word,如果這個進程沒有多線程,如果有個定時保存文檔的功能,當自動保存的時候,還能繼續輸入文字嗎?當然是不能的。因為單線程只能干一件事,無法并發和并性,直接導致用戶體驗不好。CPU的快速運算能力還有多核就被浪費了。 那么為什么不能用多進程來處理呢?一個進程來接受用戶輸入的文字,另一個進程來自動保存。但是我們需要知道,進程之間是相互隔離的,他們要共享數據,是非常麻煩的。比如說要共享被編輯的文件內容并不容易。 可以說,進程是擁有資源的基本單位,線程是CPU調度的基本單位。 比如有兩個進程,word和QQ。 Word進程打開文件,這是它的資源,QQ打開了Socket,這也是它的資源。 假設word有兩個線程,T1負責用戶文字輸入,T2負責自動保存 QQ也有兩個線程,T3負責從Socket讀取數據,T4負責對音樂數據進行解碼。 操作系統在做調度的時候,基本單位不是word,QQ,而是T1,T2,T3這些線程。 ![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180824095135.png?picgo) 每個線程執行的都是進程代碼中的某個片段。 我們知道Java中總是討論多線程編程,但是從來沒有提過Java多進程,為什么呢? 因為java是一運行在JVM中,對于操作系統來說,JVM就是java.exe運行起來,也就是個進程。 所以說JVM這個進程其實就是他們的容器。 另外Python等動態語言也有虛擬機,也可以進行多線程編程了。 所以說虛擬機是個好東西,程序員不需要再去操作內存,可以屏蔽操作系統的差異,讓寫的程序可以任意在支持該語言虛擬機上的操作系統上運行。 為什么在Java中創建的Thread對象需要調用start方法才能啟動線程,而不是直接調用run呢?如果直接調用run的話,只是用當前線程去執行一個普通的函數,根本沒有新線程創建出來。 所以,想創建一個新的線程出來,必須有準備工作,比如設置好線程的上下文,比如棧(相當于函數調用)、線程狀態,比如線程的PC(Program Counter)等,線程才可以被調度,一旦被調度,就會執行run()方法了。 ## 線程池 既然線程是屬于進程的,那么創建一個線程應該很輕松啊,為什么要有線程池這個東西呢? 因為線程雖然輕量,但是對與互聯網應用,每個用戶的請求都創建一個線程,那會非常多。而且眾多的線程去競爭CPU,不斷的切換,也會讓CPU調度不堪重負,很多線程不得不等待。 所以最好的方法用少量的線程,并且讓這些線程盡可能充分利用。也就是說只創建一定數量的線程,讓這些線程來處理所有的任務,任務執行完了以后,線程不結束,而是回到線程池里面,等待接受下一個任務。 ![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180824100039.png?picgo) 這些線程可以預先創建,任務來就不用臨時再創建了,可以立刻開始服務。 但是線程是程序代碼的執行,是個動態的東西,怎么可以預先創建呢? 這是因為線程是有狀態的,當線程池的線程剛剛創建的時候,會讓他們進入阻塞狀態:等待任務的到來。如果任務來了,就喚醒其中的線程,讓它拿到任務去執行。 那如何讓線程進入阻塞狀態呢? 就是一個線程調用take()方法取數據的時候,如果這個Queue中沒有數據,該線程就會阻塞,同樣一個線程調用它的put方法放數據的時候,如果Queue滿了,也會阻塞。 ![](http://p8a6vmhkm.bkt.clouddn.com/picgo20180824100323.png?picgo) 所以說線程池的每個線程的run()方法中,要設置一個循環,每次都嘗試從BlockingQueue獲取任務,如果Queue是空的,就阻塞等待,如果有任務來了,就會通知到線程吃的某個線程去處理,櫥窗完了,試圖從BlockingQueue中獲取任務,依次循環下去。 ~~~ 線程池中的Worker線程: public class WorkerThread extends Thread { private BlockingQueue<Task> taskQueue = null; private boolean isStopped = false; //持有一個BlockingQueue的實例 public WorkerThread(BlockingQueue<Task> queue){ taskQueue = queue; } public void run(){ while(!isStopped()){ try{ Task task = taskQueue.take(); task.execute(); } catch(Exception e){ //log or otherwise report exception, //but keep pool thread alive. } } } ......略...... } ~~~ 這套代碼已經被吸收到JDK,作為java.util.concurrent包的一部分。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看