成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java多線程從創建開始—創建和使用以及了解多線程的切換策略

開發 前端
成員變量共同使用,如果不定義為static,則繼承Thread類就是各自使用各自的,但是實現Runnable接口,只需要創建一次對象,成員變量也相當于是共享的。

方式一:繼承Thread類

  1. 繼承Thread類
  2. 重寫run方法,在run方法中添加想要線程執行的內容
  3. 創建繼承Thread類的類對象
  4. 調用start方法,一個對象只允許調用一次start方法,否則報錯java.lang.IllegalThreadStateException
  5. 每一個對象調用一次start方法就是一個線程

注意事項:

  1. 用戶手動調用run()方法并不會啟動線程,必須通過start()方法告訴JVM虛擬機使用run()方法啟動線程
  2. 為什么要重寫run方法呢? 因為run方法是用來封裝被線程執行的代碼
  3. run()和start()方法的區別? run():封裝線程執行的代碼,直接調用,相當于普通方法的調用 start():啟動線程,然后由JVM調用此線程的run()方法啟動線程
public class MultithreadingTest extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("這是線程"+i+currentThread().getName());
        }
    }

    public static void main(String[] args) {
        MultithreadingTest mt=new MultithreadingTest();
        mt.start();//Exception in thread "main" java.lang.IllegalThreadStateException
        MultithreadingTest mt1=new MultithreadingTest();
        mt1.start();
        //mt.start();
    }
}

方式二:實現Runable接口

  1. 實現Runnable接口
  2. 重寫run方法,在run方法中添加想要線程執行的內容
  3. 創建實現Runnable接口的類對象
  4. 創建多個Thread實例對象,將實現了Runnable接口的實例對象放入Thread實例對象中
  5. 調用start方法,一個Thread實例對象只能調用一次start方法,否則報錯java.lang.IllegalThreadStateException
  6. 每個Thread對象調用一次start方法就代表一個線程
class RunnableTest implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("這是Runnable線程"+i+"-->"+Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {
        RunnableTest rt=new RunnableTest();
        Thread t1=new Thread(rt,"t1");
        Thread t2=new Thread(rt,"t2");
        Thread t3=new Thread(rt,"t3");
        t1.start();
        t2.start();
        t3.start();
    }
}

方式三:實現Callable接口

  1. 實現Callable接口,需要返回值類型,返回值為泛型類型,如果沒有泛型則默認為Object
  2. 重寫call方法,需要拋出異常
  3. 創建繼承了Callable接口的類對象
  4. 創建FutureTask對象,傳入繼承了Callable接口的類對象
  5. new Thread(FutureTask的實例對象).start()
  6. 如果需要取call方法的返回值,則使用get方法
class CallableTest implements Callable {
    @Override
    public Object call() throws Exception {
        int num=0;
        for (int i = 1; i <= 100; i++) {
            if (i%2==0) {
                System.out.println(i);
                num += i;
            }
        }
        return num;
    }

    public static void main(String[] args) {
        CallableTest ct=new CallableTest();
        FutureTask ft=new FutureTask(ct);
        new Thread(ft).start();
        try {
            int i= (Integer) ft.get();
            System.out.println("總和為:"+i);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

方式四:線程池的方式

  1. 實現Callable接口,需要返回值類型,返回值為泛型類型,如果沒有泛型則默認為Object
  2. 重寫call方法,需要拋出異常
  3. 創建繼承了Callable接口的類對象
  4. 創建執行服務ExecutorService類對象(創建線程池),并設定線程數
  5. 提交執行服務es.submit(),提交數不可超過設定的線程數,超過的線程數不生效關閉服務es.shutdownNow()
/**
* 線程池相關API:ExecutorService和Excutors
* ExcutorService:真正的線程池接口;常見的子類ThreadPoolExcutor
*   1.void execute(Runnable command):執行任務/命令,沒有返回值,一般用來執行Runnable
*  2.<T>Future<T> submit(Callable<T> task):執行任務,有返回值,一般用來執行Callable
*  3.void shutdown():關閉連接池
* Executors:工具類、線程池的工廠類,用于創建并返回不同類型的線程池
*  1.Executors.newCachedThreadPool():創建一個可根據需要創建新線程的線程池
*  2.Executors.newFixedThreadPool(n):創建一個可重用固定線程數的線程池
*  3.Executors.newSingleThreadExecutor():創建一個只有一個線程的線程池
*  4.Executors.newScheduledThreadPool(n):創建一個線程池,它可安排在給定延遲后運行命令或定期地執行
*/
class CallAbleTest implements Callable<Boolean>{
    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("這是Callable線程"+i+"-->"+Thread.currentThread().getName());
        }
        return true;
    }

    public static void main(String[] args) {
        CallAbleTest ct=new CallAbleTest();

        //創建執行服務
        ExecutorService es= Executors.newFixedThreadPool(3);
        //提交執行
        Future<Boolean> f1=es.submit(ct);
        Future<Boolean> f2=es.submit(ct);
        Future<Boolean> f3=es.submit(ct);
        Future<Boolean> f4=es.submit(ct);
        //獲取結果
        try {
            boolean r1=f1.get();
            boolean r2=f2.get();
            boolean r3=f3.get();
            boolean r4=f4.get();
            System.out.println("r1 = " + r1+" r2 = " + r2+" r3 = " + r3+" r4="+r4);;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        //關閉服務
        es.shutdownNow();
    }
}

Thread和Runnable對比

重點說明:

在開發中Thread和Runnable優先選擇實現Runnable接口

原因:

  1. 實現的方式沒有類的單繼承的局限性
  2. 實現的方式更適合處理多個線程有共享數據的情況

舉例說明:成員變量共同使用,如果不定義為static,則繼承Thread類就是各自使用各自的,但是實現Runnable接口,只需要創建一次對象,成員變量也相當于是共享的

實現Callable接口比Runnable強大 原因:

  1. call方法有返回值
  2. call方法可以拋出異常并捕獲(使用get方法)

線程池的創建重點:

  1. 線程池的大小一般為服務器核數*2+有效磁盤數
  2. 線程池內的線程可以頻繁使用,使用完了會歸還而不會銷毀(重復利用)
  3. 減少頻繁創建和銷毀消耗大量的時間(空間換時間)
  4. 線程池的設計可以便于管理,避免多用戶創建導致的宕機

出現線程安全問題的原因: 當多條語句在操作同一個線程共享數據時,一個線程對多條語句只執行了一部分,還沒有執行完,另一個線程參與進來執行,導致共享數據錯誤

解決辦法: 對多條操作共享數據的語句,只能讓一個線程都執行完,在執行過程中不允許其他線程參與執行

多線程調度策略

  • 分時調度模型:

時間片策略:所有線程輪流使用CPU的使用權,平均分配每個線程占用的CPU的時間片

優先級調度策略:根據線程的優先級來分配CPU資源,高優先級的線程優先執行

同優先級線程是先進先出的隊列,使用時間片策略;不同優先級線程采用優先級調度策略

  • 搶占式調度模型:

對高優先級的使用優化調度的搶占式策略

搶占式策略:優先讓優先級高的線程使用CPU,如果線程的優先級相同,那么會隨機選擇一個,優先級高的線程獲取CPU時間片相對多一些

  • 線程的優先級等級

MAX_PRIORITY:10【最高優先級】

MIN_PRIORITY:1【最低優先級】

NORM_PRIORITY:5【默認優先級】

  • 優先級的方法

getPriority():返回線程優先值

setPriority(int newPriority):改變線程的優先級,數越大優先級越高

  • 說明:

線程創建時,繼承父線程的優先級

低優先級只是獲得調度的概率低,并非一定是在高優先級線程之后才被調用

對應Windows線程優先級

Java線程優先級

Windows線程優先級

1(Thread.MIN_PRIORITY)

THREAD_PRIORITY_LOWEST

2

THREAD_PRIORITY_LOWEST

3

THREAD_PRIORITY_BELOW_NORMAL

5(Thread.NORM_PRIORITY)

THREAD_PRIORITY_NORMAL

6

THREAD_PRIORITY_ABOVE_NORMAL

7

THREAD_PRIORITY_ABOVE_NORMAL

8

THREAD_PRIORITY_HIGHEST

9

THREAD_PRIORITY_HIGHEST

10(Thread.MAX_PRIORITY)

THREAD_PRIORITY_GRITICAL

優先級的方法

  • getPriority():返回線程優先值
  • setPriority(int newPriority):改變線程的優先級,數越大優先級越高

說明:

  • 線程創建時,繼承父線程的優先級
  • 低優先級只是獲得調度的概率低,并非一定是在高優先級線程之后才被調用
責任編輯:武曉燕 來源: 愛編程的杰尼龜
相關推薦

2023-06-06 08:17:52

多線程編程Thread類

2010-03-10 08:54:49

Python多線程

2009-06-29 18:00:05

Java多線程Runnable接口創建線程

2010-03-15 17:56:23

Java多線程

2009-06-29 17:54:10

Java多線程Thread類創建線程

2010-02-01 17:18:23

Python多線程環境

2021-02-25 15:58:46

C++線程編程開發技術

2016-11-10 16:30:22

Java多線程

2009-03-12 10:52:43

Java線程多線程

2021-09-11 15:26:23

Java多線程線程池

2009-08-12 13:22:44

Singleton模式

2019-02-26 11:15:25

進程多線程多進程

2009-06-29 17:49:47

Java多線程

2021-12-26 18:22:30

Java線程多線程

2010-03-17 14:58:20

Java多線程

2011-06-16 10:38:13

Qt多線程編程

2009-06-29 18:08:51

Java多線程join方法

2011-07-01 11:18:50

Qt 多線程

2011-04-14 13:27:53

Synchronize多線程

2009-06-29 18:22:54

Java多線程從線程返回數據
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91在线精品一区二区 | 欧美一级久久久猛烈a大片 日韩av免费在线观看 | 色毛片 | 久草在线高清 | 国产午夜在线 | 成人免费在线播放视频 | 自拍偷拍精品 | 欧美久久精品一级黑人c片 91免费在线视频 | 精品粉嫩aⅴ一区二区三区四区 | 欧美一区二区在线 | 伊人精品| 男女爱爱网站 | 91精品国产乱码久久蜜臀 | 国产黄色电影 | 国产精品欧美一区二区三区 | 国产女人精品视频 | 国产欧美在线一区二区 | 日韩中文字幕 | 一区二区三区在线播放 | 91精品在线播放 | 97久久精品午夜一区二区 | 丁香久久 | 日本不卡免费新一二三区 | 色噜噜亚洲男人的天堂 | 亚洲福利在线视频 | 午夜二区| 国产精品我不卡 | 天天影视网天天综合色在线播放 | 久久久精品久 | 99久久久无码国产精品 | 日本免费在线 | 91一区二区在线观看 | 国产在线精品一区二区 | 91在线精品播放 | 午夜午夜精品一区二区三区文 | 免费观看黄色一级片 | 日本超碰在线 | 人人叉| 国产在线一区二区 | 免费在线看a | 久久99精品国产麻豆婷婷 |