java中的線程問題

來源:互聯網
上載者:User

標籤:證明   count   簡單   lan   stat   上傳   今天   精度   dsl   

                 今天簡單介紹一下單線程的相關內容。

                  線程是java中的重要內容,有時也被稱為輕量級進程,是程式執行流的最小單元 。線程是程式中一個單一的順序控制流程程,在單個程式中同時運行多個線程完成不同的工作,稱為多線程。

                  電腦程式得以執行的3個要素是:CPU,程式碼和可存取的資料。在java語言中,多線程的機制是通過虛擬CPU來實現的,可以形象的理解為,在一個java語言內部虛擬了多台電腦,每台電腦對應一個線程,有自己的CPU,可以擷取所需的代碼和資料,因此能獨立執行任務,相互之間還可以共用代碼和資料。

                   java的線程是通過java.lang.Thread類來實現的,它內部實現了虛擬CPU的功能,能夠接收和處理傳遞給它的代碼和資料,並提供了獨立的運行控制功能。

                  下面看一下Thread類的源碼:

                     再看看Runable介面的源碼:

 

                     可見Thread類實現了Runnable介面,同時在Thread類中,有一些比較關鍵的屬性,比如name是表示Thread的名字,可以通過Thread類的構造器中的參數來指定線程名字,priority表示線程的優先順序(最大值為10,最小值為1,預設值為5),daemon表示線程是否是守護線程,target表示要執行的任務。我們在建立線程的時候,一種方式就是通過Thread來實現,第二種是通過實現Runable介面並實現介面中定義的唯一的方法run()。這兩種方法各有各的好處和缺點:直接繼承Thread類:不能再從其他類繼承;編寫簡單,可以直接操縱線程;使用Runable介面:可以將CPU,代碼和資料分開,形成清晰的模型,還可以再從其他類繼承,保持了程式風格的一致性。

                     Thread類中還有一些方法,我複製了CSDN中seapeak007的部落格內容,覺得總結的不錯。

                      方法摘要 
static int activeCount() 
          返回當前線程的線程組中活動線程的數目。 
 void checkAccess() 
          判定當前啟動並執行線程是否有權修改該線程。 
 int countStackFrames() 
          已淘汰。 該調用的定義依賴於 suspend(),但它遭到了反對。此外,該調用的結果從來都不是意義明確的。 
static Thread currentThread() 
          返回對當前正在執行的線程對象的引用。 
 void destroy() 
          已淘汰。 該方法最初用於破壞該線程,但不作任何清除。它所保持的任何監視器都會保持鎖定狀態。不過,該方法決不會被實現。即使要實現,它也極有可能以 suspend() 方式被死結。如果目標線程被破壞時保持一個保護關鍵系統資源的鎖,則任何線程在任何時候都無法再次訪問該資源。如果另一個線程曾試圖鎖定該資源,則會出現死結。這類死結通常會證明它們自己是“凍結”的進程。有關更多資訊,請參閱為何不贊成使用 Thread.stop、Thread.suspend 和 Thread.resume?。 
static void dumpStack() 
          將當前線程的堆疊追蹤列印至標準錯誤流。 
static int enumerate(Thread[] tarray) 
          將當前線程的線程組及其子組中的每一個活動線程複製到指定的數組中。 
static Map<Thread,StackTraceElement[]> getAllStackTraces() 
          返回所有活動線程的堆疊追蹤的一個映射。 
 ClassLoader getContextClassLoader() 
          返回該線程的上下文 ClassLoader。 
static Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() 
          返回線程由於未捕獲到異常而突然終止時調用的預設處理常式。 
 long getId() 
          返回該線程的標識符。 
 String getName() 
          返回該線程的名稱。 
 int getPriority() 
          返回線程的優先順序。 
 StackTraceElement[] getStackTrace() 
          返回一個表示該線程堆棧轉儲的堆疊追蹤元素數組。 
 Thread.State getState() 
          返回該線程的狀態。 
 ThreadGroup getThreadGroup() 
          返回該線程所屬的線程組。 
 Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() 
          返回該線程由於未捕獲到異常而突然終止時調用的處理常式。 
static boolean holdsLock(Object obj) 
          若且唯若當前線程在指定的對象上保持監視器鎖時,才返回 true。 
 void interrupt() 
          中斷線程。 
static boolean interrupted() 
          測試當前線程是否已經中斷。 
 boolean isAlive() 
          測試線程是否處於活動狀態。 
 boolean isDaemon() 
          測試該線程是否為守護線程。 
 boolean isInterrupted() 
          測試線程是否已經中斷。 
 void join() 
          等待該線程終止。 
 void join(long millis) 
          等待該線程終止的時間最長為 millis 毫秒。 
 void join(long millis, int nanos) 
          等待該線程終止的時間最長為 millis 毫秒 + nanos 納秒。 
 void resume() 
          已淘汰。 該方法只與 suspend() 一起使用,但 suspend() 已經遭到反對,因為它具有容易導致鎖死的。有關更多資訊,請參閱為何不贊成使用 Thread.stop、Thread.suspend 和 Thread.resume?。 
 void run() 
          如果該線程是使用獨立的 Runnable 運行物件建構的,則調用該 Runnable 對象的 run 方法;否則,該方法不執行任何操作並返回。 
 void setContextClassLoader(ClassLoader cl) 
          設定該線程的上下文 ClassLoader。 
 void setDaemon(boolean on) 
          將該線程標記為守護線程或使用者線程。 
static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 
          設定當線程由於未捕獲到異常而突然終止,並且沒有為該線程定義其他處理常式時所調用的預設處理常式。 
 void setName(String name) 
          改變線程名稱,使之與參數 name 相同。 
 void setPriority(int newPriority) 
          更改線程的優先順序。 
 void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 
          設定該線程由於未捕獲到異常而突然終止時調用的處理常式。 
static void sleep(long millis) 
          在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行),此操作受到系統計時器和發送器精度和準確性的影響。 
static void sleep(long millis, int nanos) 
          在指定的毫秒數加指定的納秒數內讓當前正在執行的線程休眠(暫停執行),此操作受到系統計時器和發送器精度和準確性的影響。 
 void start() 
          使該線程開始執行;JAVA 虛擬機器調用該線程的 run 方法。 
 void stop() 
          已淘汰。 該方法具有固有的不安全性。用 Thread.stop 來終止線程將釋放它已經鎖定的所有監視器(作為沿堆棧向上傳播的未檢查 ThreadDeath 異常的一個自然後果)。如果以前受這些監視器保護的任何對象都處於一種不一致的狀態,則損壞的對象將對其他線程可見,這有可能導致任意的行為。stop 的許多使用都應由只修改某些變數以指示目標線程應該停止啟動並執行代碼來取代。目標線程應定期檢查該變數,並且如果該變數指示它要停止運行,則從其運行方法依次返回。如果目標線程等待很長時間(例如基於一個條件變數),則應使用 interrupt 方法來中斷該等待。有關更多資訊,請參閱為何不贊成使用 Thread.stop、Thread.suspend 和 Thread.resume?。 
 void stop(Throwable obj) 
          已淘汰。 該方法具有固有的不安全性。有關詳細資料,請參閱 stop()。該方法的附加危險是它可用於產生目標線程未準備處理的異常(包括若沒有該方法該線程不太可能拋出的已檢查的異常)。有關更多資訊,請參閱為何不贊成使用 Thread.stop、Thread.suspend 和 Thread.resume?。 
 void suspend() 
          已淘汰。 該方法已經遭到反對,因為它具有固有的容易導致鎖死的。如果目標線程掛起時在保護關鍵系統資源的監視器上保持有鎖,則在目標線程重新開始以前任何線程都不能訪問該資源。如果重新開始目標線程的線程想在調用 resume 之前鎖定該監視器,則會發生死結。這類死結通常會證明自己是“凍結”的進程。有關更多資訊,請參閱為何不贊成使用 Thread.stop、Thread.suspend 和 Thread.resume?。 
 String toString() 
          返回該線程的字串表示形式,包括線程名稱、優先順序和線程組。 
static void yield() 
          暫停當前正在執行的線程對象,並執行其他線程。 

                      接下來說說線程的基本狀態。線程的狀態分為4種:建立(New),可運行(Runable),阻塞(Blocked)和死亡(Dead)。

                      下面說說執行情況。當使用new來建立一個線程時,它處於建立狀態,這個時候,線程並未進行任何操作,然後調用線程的start()方法,來向線程發送器(通常是JVM(java虛擬機器)或作業系統)註冊一個線程,這個時候,這個線程一切就緒,就等待CPU時間了。線程發送器根據調度策略來調度不同的線程,調用線程的run()方法給已經註冊的各個線程以執行的機會,被調度的程式進入運行(Running)狀態。當線程的run()方法運行完畢,線程將被拋棄,進入死亡(Dead)狀態。不能調用restart()方法來重新開始一個處於死亡狀態的線程,但是可以調用處於死亡狀態的線程對象的各個方法。如果線程在運行(Running)狀態中因為I/O阻塞,等待鍵盤輸入,調用了線程的sleeo()方法,調用了對象的wait()方法等,則線程將進入阻塞(Blocked)狀態,直到這些阻塞原因被解除。線程發送器會根據調度情況,將正在運行(Running)中的線程設定為Runable狀態。

                     線程的結束方式有以下幾種:1.讓線程的Run()方法執行完,線程自然結束(此方法最好);2.通過輪詢和共用標誌位的方法來結束線程;3.線程拋出一個未捕獲(Catch)到的Exception或Erro,通過調用interrupt方法和捕獲InterruptedException異常來終止線程;4.使用線程池,當線程不用了,就讓它sleep並放進隊列中。

 

java中的線程問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.