<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      線程專題 -- 線程的創(chuàng)建,狀態(tài),工作過程,常見方法

      線程(Thread)是并發(fā)編程的基礎(chǔ),一般會作為并發(fā)編程的起始問題,用于引出更多的關(guān)于并發(fā)編程的面試問題。對于線程的掌握程度也決定了你對并發(fā)編程的掌握程度。

      什么是進(jìn)程?線程?區(qū)別?

      詳細(xì)介紹請查閱我的另一篇博文——進(jìn)程?線程?協(xié)程?

      線程安全?

      詳細(xì)介紹請查閱我的另一篇博文——線程安全

      創(chuàng)建線程的方式?區(qū)別?

      詳細(xì)介紹請查閱我的另一篇博文——三種線程創(chuàng)建的方式

      線程的狀態(tài)有哪些?

      線程的狀態(tài)在 JDK 1.5 之后以枚舉的方式被定義在 Thread 的源碼中,它總共包含以下 6 個狀態(tài):

      線程狀態(tài)的源代碼如下:

      (1)NEW,新建狀態(tài),線程被創(chuàng)建出來,但尚未啟動時的線程狀態(tài);

      (2)RUNNABLE,就緒狀態(tài),表示可以運行的線程狀態(tài),它可能正在運行,或者是在排隊等待操作系統(tǒng)給它分配 CPU 資源;

      (3)BLOCKED,阻塞等待鎖的線程狀態(tài),表示處于阻塞狀態(tài)的線程正在等待監(jiān)視器鎖,比如等待執(zhí)行 synchronized 代碼塊或者使用 synchronized 標(biāo)記的方法;

      (4) WAITING,等待狀態(tài),一個處于等待狀態(tài)的線程正在等待另一個線程執(zhí)行某個特定的動作,比如,一個線程調(diào)用了Object.wait()方法,那它就在等待另一個線程調(diào)用Object.notify()或 Object.notifyAll() 方法;

      (5)TIMED_WAITING,計時等待狀態(tài),和等待狀態(tài)(WAITING)類似,它只是多了超時時間,比如調(diào)用了有超時時間設(shè)置的方法Object.wait(longtimeout)和Thread.join(long timeout) 等這些方法時,它才會進(jìn)入此狀態(tài);

      (6)TERMINATED,終止?fàn)顟B(tài),表示線程已經(jīng)執(zhí)行完成。

      如果想要確定線程當(dāng)前的狀態(tài),可以通過 getState() 方法,并且線程在任何時刻只可能處于 1 種狀態(tài)。

      線程是如何工作的?(工作過程?)

        首先先要創(chuàng)建線程并指定線程需要執(zhí)行的業(yè)務(wù)方法,然后再調(diào)用線程的start()方法,此時線程就從NEW(新建)狀態(tài)變成了RUNNABLE(就緒)狀態(tài),然后線程會判斷要執(zhí)行的方法中有沒有 synchronized 同步代碼塊,如果有并且其他線程也在使用此鎖,那么線程就會變?yōu)?BLOCKED(阻塞等待鎖的線程)狀態(tài),當(dāng)其他線程使用完此鎖之后,線程會繼續(xù)執(zhí)行剩余的方法。當(dāng)遇到Object.wait()或Thread.join()方法時,線程會變?yōu)閃AITING(等待狀態(tài))狀態(tài),如果是帶了超時時間的等待方法,那么線程會進(jìn)入TIMED_WAITING(計時等待)狀態(tài),當(dāng)有其他線程執(zhí)行了notify()或notifyAll()方法之后,線程被喚醒繼續(xù)執(zhí)行剩余的業(yè)務(wù)方法,直到方法執(zhí)行完成為止,此時整個線程的流程就執(zhí)行完了。

      start() 和run() 方法有什么區(qū)別?

      源碼分析:

      (1) start() 方法屬于 Thread 自身的方法,并且使用了 synchronized 來保證線程安全。它的作用是啟動一個新線程。通過start()方法來啟動的新線程,從NEW(新建)狀態(tài)變成了處于RUNNABLE(就緒)狀態(tài),并沒有運行,一旦得到cpu時間片,就開始執(zhí)行相應(yīng)線程的run()方法,這里方法run()稱為線程體,它包含了線程要執(zhí)行的業(yè)務(wù)方法,run方法運行結(jié)束,此線程隨即終止。

      源碼如下:

       (2)run() 方法為 Runnable 的抽象方法,必須由調(diào)用類重寫此方法,重寫的 run() 方法其實就是此線程要執(zhí)行的業(yè)務(wù)方法;run() 就和普通的成員方法一樣,可以被重復(fù)調(diào)用,如果直接調(diào)用run方法,并不會啟動新線程!程序中依然只有主線程這一個線程,其程序執(zhí)行路徑還是只有一條,還是要順序執(zhí)行。

      源碼如下:

       Thred實現(xiàn)Runnable接口,重寫run方法,源碼如下

       

      區(qū)別

       (1) start() 可以啟動一個新線程,讓線程從NEW狀態(tài)轉(zhuǎn)換成RUNNABLE狀態(tài),而run()不能,只是一個普通的方法。

       (2) start()不能被重復(fù)調(diào)用(否則會拋出 java.lang.IllegalStateException),而 run() 方法可以進(jìn)行多次調(diào)用,因為它只是一個普通的方法而已。

       (3)start()中的run代碼可以不執(zhí)行完就繼續(xù)執(zhí)行下面的代碼,即進(jìn)行了線程切換。直接調(diào)用run方法必須等待其代碼全部執(zhí)行完才能繼續(xù)執(zhí)行下面的代碼。

      線程的優(yōu)先級有什么用?該如何設(shè)置?

      線程的優(yōu)先級可以理解為線程搶占 CPU 時間片的概率,優(yōu)先級越高的線程優(yōu)先執(zhí)行的概率就越大,但并不能保證優(yōu)先級高的線程一定先執(zhí)行。

      在程序中我們可以通過 Thread.setPriority() 來設(shè)置優(yōu)先級,setPriority() 源碼如下:

      線程的常用方法?

       join()

      詳細(xì)介紹請查閱我的另一篇博文——等待線程執(zhí)行終止的 join 方法

      yield()

      看 Thread 的源碼可以知道 yield() 為本地方法,也就是說 yield() 是由 C 或 C++ 實現(xiàn)的,源碼如下:

        Thread類中有一個靜態(tài)的yield方法,當(dāng)一個線程調(diào)用yield方法時,實際就是在暗示線程調(diào)度器當(dāng)前線程請求讓出自己的CPU使用,但是線程調(diào)度器可以無條件忽略這個暗示。我們知道操作系統(tǒng)是為每個線程分配一個時間片來占有CPU的,正常情況下當(dāng)一個線程把分配給自己的時間片使用完后,線程調(diào)度器才會進(jìn)行下一輪的線程調(diào)度,而當(dāng)一個線程調(diào)用了Thread類的靜態(tài)方法yield時,是在告訴線程調(diào)度器自己占有的時間片中還沒有使用完的部分自己不想使用了,這暗示線程調(diào)度器現(xiàn)在就可以進(jìn)行下一輪的線程調(diào)度。

        當(dāng)一個線程調(diào)yield方法時,當(dāng)前線程會讓出CPU使用權(quán),然后處于就緒狀態(tài),線程調(diào)度器會從線程就緒隊列里面獲取一個線程優(yōu)先級最高的線程,當(dāng)然也有可能會調(diào)度到剛剛讓出CPU的那個線程來獲取CPU執(zhí)行權(quán)。

      Java多線程中調(diào)用wait() 和 sleep()方法有什么不同?

      詳細(xì)介紹請查閱我的另一篇博文——Java多線程中調(diào)用wait() 和 sleep()方法有什么不同?

      Java中notify 和 notifyAll有什么區(qū)別?

       調(diào)用notify時,只有一個等待線程會被喚醒而且它不能保證哪個線程會被喚醒,這取決于線程調(diào)度器。如果你調(diào)用notifyAll方法,那么等待該鎖的所有線程都會被喚醒。

       Java中interrupted 和 isInterruptedd方法的區(qū)別?

        interrupted() 和 isInterrupted()的主要區(qū)別是前者會將中斷狀態(tài)清除而后者不會。

        Java多線程的中斷機制是用內(nèi)部標(biāo)識來實現(xiàn)的,調(diào)用Thread.interrupt()來中斷一個線程就會設(shè)置中斷標(biāo)識為true。當(dāng)中斷線程調(diào)用靜態(tài)方法Thread.interrupted()來檢查中斷狀態(tài)時,中斷狀態(tài)會被清零。而非靜態(tài)方法isInterrupted()用來查詢其它線程的中斷狀態(tài)且不會改變中斷狀態(tài)標(biāo)識。簡單的說就是任何拋出InterruptedException異常的方法都會將中斷狀態(tài)清零。無論如何,一個線程的中斷狀態(tài)有有可能被其它線程調(diào)用中斷來改變。

      什么是ThreadLocal?

        ThreadLocal用于創(chuàng)建線程的本地變量,我們知道一個對象的所有線程共享它的全局變量,所以這些變量是非線程安全的,我們可以使用同步技術(shù)。但是當(dāng)我們不想使用同步的時候,我們可以選擇ThreadLocal變量。每個線程都會擁有他們自己的Thread變量,它們可以使用get()/set()方法去獲取他們的默認(rèn)值或者在線程內(nèi)部改變他們的值。

       如何創(chuàng)建守護(hù)線程?

        使用Thread類的setDaemon(true)方法可以將線程設(shè)置為守護(hù)線程,需要注意的是,需要在調(diào)用start()方法前調(diào)用這個方法,否則會拋出IllegalThreadStateException異常。

      /**
       * @author liao.wenhui
       * @date 2019/7/15 15:13
       */
      public class DaemonThread {
          public static void main(String[] args) {
              Thread daemonThread = new Thread(new Runnable() {
                  @Override
                  public void run() {
      
                  }
              });
      
              //設(shè)置守護(hù)線程
              daemonThread.setDaemon(true);
              daemonThread.start();
          }
      }

      前提知識:

        守護(hù)進(jìn)程(Daemon)是運行在后臺的一種特殊進(jìn)程。它獨立于控制終端并且周期性地執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件(百度百科)。

        Java線程分為兩類分別為daemon線程(守護(hù)線程)和User線程(用戶線程),在JVM啟動時候會調(diào)用main函數(shù),main函數(shù)所在的線程是一個用戶線程,這個是我們可以看到的線程,其實JVM內(nèi)部同時還啟動了好多守護(hù)線程,比如垃圾回收線程。那么守護(hù)線程和用戶線程有什么區(qū)別那?區(qū)別之一是當(dāng)最后一個非守護(hù)線程結(jié)束時候,JVM會正常退出,而不管當(dāng)前是否有守護(hù)線程,也就是說守護(hù)線程是否結(jié)束并不影響JVM的退出。言外之意是只要有一個用戶線程還沒結(jié)束正常情況下JVM就不會退出。

      什么是線程調(diào)度器(Thread Scheduler)和時間分片(Time Slicing)?

        線程調(diào)度器是一個操作系統(tǒng)服務(wù),它負(fù)責(zé)為Runnable狀態(tài)的線程分配CPU時間。一旦我們創(chuàng)建一個線程并啟動它,它的執(zhí)行便依賴于線程調(diào)度器的實現(xiàn)。

        時間分片是指將可用的CPU時間分配給可用的Runnable狀態(tài)的線程的過程。分配CPU時間可以基于線程優(yōu)先級或者線程等待的時間。線程調(diào)度并不受到Java虛擬機控制,所以由應(yīng)用程序來控制它是更好的選擇(即最好不要讓你的程序依賴于線程的優(yōu)先級)。

      在多線程中,什么是上下文切換?

      上下文切換是存儲和恢復(fù)CPU狀態(tài)的過程,它使得線程執(zhí)行能夠從中斷點恢復(fù)執(zhí)行。是多任務(wù)操作系統(tǒng)和多線程環(huán)境的基本特征。 

      并發(fā)編程三要素

      (1) 原子性:程序中的所有操作是不可中斷的,要么全部執(zhí)行成功要么全部執(zhí)行失敗。

      (2) 有序性:程序執(zhí)行的順序按照代碼的先后順序執(zhí)行。(處理器可能會對指令進(jìn)行重排序)

      (3) 可見性:當(dāng)多個線程訪問同一個變量時,如果其中一個線程對其作了修改,其他線程能立即獲取到最新的值。

      參考/好文:

      Java 面試真題及源碼 34 講

      -- https://kaiwu.lagou.com/course/courseInfo.htm?courseId=59

       <END>

      ??希望本文章對您有幫助,您的 轉(zhuǎn)發(fā)、點贊 是我創(chuàng)作的無限動力。

      掃描下方二維碼關(guān)注微信公眾號,您會收到更多優(yōu)質(zhì)文章推送。

       

      posted @ 2019-07-14 17:22  JustJavaIt  閱讀(9167)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 国产成人亚洲欧美二区综合| 美女又黄又免费的视频| 在线亚洲高清揄拍自拍一品区| japan黑人极大黑炮| 久久久久国产一区二区| 精品精品国产国产自在线| 一本色道久久综合熟妇人妻| 同性男男黄gay片免费| 亚洲色大成网站WWW永久麻豆| 国产熟女一区二区三区蜜臀| 国产精品va在线观看无码| 国产精品一区二区三区色| 九九热在线观看精品视频| 香蕉在线精品一区二区| 亚洲精品国产无套在线观| 极品尤物被啪到呻吟喷水| 无码人妻精品一区二| 潮喷失禁大喷水无码| 国产成人午夜一区二区三区| 日韩av无码精品人妻系列| 天堂av在线一区二区| 亚洲国产美女精品久久久| 色综合AV综合无码综合网站| 九九电影网午夜理论片| 人妻少妇偷人无码视频| 国产精品人妻久久ai换脸| 野外做受三级视频| 素人视频亚洲十一十二区| 国精产品一品二品国精在线观看 | 国产精品一线二线三线区| 浪潮av色综合久久天堂| 中文字幕av无码免费一区| 色琪琪丁香婷婷综合久久| 久久国产成人精品国产成人亚洲| 精品免费看国产一区二区| 日韩欧美aⅴ综合网站发布| 国产精品中文字幕一区| 亚洲精品成人无限看| 国产一区二区视频啪啪视频 | 少妇人妻互换不带套| 国产午夜精品理论片久久影院|