日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

多线程—Thread类及线程三种创建方式及对比

發布時間:2023/12/18 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多线程—Thread类及线程三种创建方式及对比 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

線程創建的3種方法:

1、繼承Thread類并重寫run方法

Thread類方法:

Thread Thread.currentThread() :獲得當前線程的引用。獲得當前線程后對其進行操作。 Thread.UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() :返回線程由于未捕獲到異常而突然終止時調用的默認處理程序。 int Thread.activeCount():當前線程所在線程組中活動線程的數目。 void dumpStack() :將當前線程的堆棧跟蹤打印至標準錯誤流。 int enumerate(Thread[] tarray) :將當前線程的線程組及其子組中的每一個活動線程復制到指定的數組中。 Map<Thread,StackTraceElement[]> getAllStackTraces() :返回所有活動線程的堆棧跟蹤的一個映射。 boolean holdsLock(Object obj) :當且僅當當前線程在指定的對象上保持監視器鎖時,才返回 true。 boolean interrupted() :測試當前線程是否已經中斷。 void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) :設置當線程由于未捕獲到異常而突然終止,并且沒有為該線程定義其他處理程序時所調用的默認處理程序。 void sleep(long millis) :休眠指定時間 void sleep(long millis, int nanos) :休眠指定時間 void yield() :暫停當前正在執行的線程對象,并執行其他線程。意義不太大 void checkAccess() :判定當前運行的線程是否有權修改該線程。 ClassLoader getContextClassLoader() :返回該線程的上下文 ClassLoader。 long getId() :返回該線程的標識符。 String getName() :返回該線程的名稱。 int getPriority() :返回線程的優先級。 StackTraceElement[] getStackTrace() :返回一個表示該線程堆棧轉儲的堆棧跟蹤元素數組。 Thread.State getState() :返回該線程的狀態。 ThreadGroup getThreadGroup() :返回該線程所屬的線程組。 Thread.UncaughtExceptionHandler getUncaughtExceptionHandler() :返回該線程由于未捕獲到異常而突然終止時調用的處理程序。 void interrupt() :中斷線程。 boolean isAlive() :測試線程是否處于活動狀態。 boolean isDaemon() :測試該線程是否為守護線程。 boolean isInterrupted():測試線程是否已經中斷。 void join() :等待該線程終止。 void join(long millis) :等待該線程終止的時間最長為 millis 毫秒。 void join(long millis, int nanos) :等待該線程終止的時間最長為 millis 毫秒 + nanos 納秒。 void run() :線程啟動后執行的方法。 void setContextClassLoader(ClassLoader cl) :設置該線程的上下文 ClassLoader。 void setDaemon(boolean on) :將該線程標記為守護線程或用戶線程。 void start():使該線程開始執行;Java 虛擬機調用該線程的 run 方法。 String toString():返回該線程的字符串表示形式,包括線程名稱、優先級和線程組。

interrupt() 并不能真正的中斷線程,只是起到標記作用,需要被調用的線程自己進行配合才行。也就是說,一個線程如果有被中斷的需求,那么就需要這樣做:

  • 在正常運行任務時,經常檢查本線程的中斷標志位,如果被設置了中斷標志就自行停止線程。
  • 在調用阻塞方法時正確處理InterruptedException異常。(例如:catch異常后就結束線程。)
  • 實現案例:?

    public class ExtendThreadTest extends Thread {@Overridepublic void run() {for (int i = 0; i < 5; i++) {System.out.println(getName() + " : run " + i);}}public static void main(String[] args) {Thread thread1 = new ExtendThreadTest();Thread thread2 = new ExtendThreadTest();thread1.start();thread2.start();for (int i = 0; i < 3; i++) {System.out.println("main : run " + i);}} }

    2、實現Runable接口并重寫run方法。Runable接口只有一個run方法。

    public class ImplementsRunnableTest implements Runnable {private int tick = 10;public void run() {while (true) {if(tick > 0){System.out.println(Thread.currentThread().getName() + "..." + tick--);}}}public static void main(String[] args) {ImplementsRunnableTest t = new ImplementsRunnableTest();new Thread(t).start();new Thread(t).start();} }

    3、通過實現Callable和Future接口創建

    public interface Callable<V> {V call() throws Exception; //類型參數V即為異步方法call的返回值類型。 }

    Future可以對具體的Runnable或者Callable任務的執行結果進行取消、查詢是否完成以及獲取結果。可以通過get方法獲取執行結果,該方法會阻塞直到任務返回結果。get方法獲取到call方法返回的數據。

    public interface Future<V> {boolean cancel(boolean mayInterruptIfRunning);boolean isCancelled(); //表示任務是否被取消成功,如果在任務正常完成前被取消成功,則返回 true。boolean isDone(); //任務是否已經完成,若任務完成,則返回trueV get() throws InterruptedException, ExecutionException; //獲取執行結果,這個方法會阻塞V get(long timeout, TimeUnit unit) //在指定時間內,還沒獲取到結果,就直接返回nullthrows InterruptedException, ExecutionException, TimeoutException; }

    java.util.concurrent包已經有自帶的Future實現類FutureTask<V>,直接用就可以了,FutureTask實現了RunnableFuture<V>接口,RunnableFuture<V>又實現了Runnable接口和Future接口。

    實現案例:?

    public class CallableTest implements Callable<String> {//重寫Callable接口方法public String call() throws Exception {return Thread.currentThread().getName();}public static void main(String[] args) {// 創建callable實現類實例CallableTest t = new CallableTest();// 使用FutureTask類來包裝Callable對象FutureTask<String> ft1 = new FutureTask<String>(t);FutureTask<String> ft2 = new FutureTask<String>(t);new Thread(ft1).start();new Thread(ft2).start();try {System.out.println(ft1.get());System.out.println(ft2.get());} catch (Exception e) {e.printStackTrace();}} }

    對比

    • 通過繼承Thread類的線程,一個類只能繼承一個父類,使得該方式具有一定的局限性。
    • 實現接口的類,再結合Thread類來實現的線程,只是實現了接口類,還可以繼承其他類,相對較靈活,且call()方法是一個有返回值而且拋異常的方法。實現接口創建的線程可以放入線程池來管理,而繼承Thread類創建的線程不可以放入線程池。
    • 三種方式最終都是通過調用start()方法來實現多線程。切記不能直接調用Thread類或Runnable對象的run()方法,因為直接調用run()方法,只會執行同一個線程中的任務,而不會啟動新線程。調用start()方法將會創建一個執行run()方法的線程。

    start()方法用了synchronized關鍵字修飾且內部調用start0()

    //native方法,JVM創建并啟動線程,并調用run方法private native void start0();

    ?

    ?

    ?

    ?

    ?

    總結

    以上是生活随笔為你收集整理的多线程—Thread类及线程三种创建方式及对比的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。