亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中創(chuàng)建線程的四種方法解析

 更新時間:2023年10月21日 10:03:29   作者:浪浪山的猿  
這篇文章主要介紹了Java中創(chuàng)建線程的四種方法解析,線程是Java編程語言中的一個重要概念,它允許程序在同一時間執(zhí)行多個任務,線程是程序中的執(zhí)行路徑,可以同時執(zhí)行多個線程,每個線程都有自己的執(zhí)行流程,需要的朋友可以參考下

前言

在 Java 中,實現多線程的主要有以下四種

  1. 繼承 Thread 類,重寫 run() 方法;
  2. 實現 Runnable 接口,實現 run() 方法,并將 Runnable 實現類的實例作為 Thread 構造函數的參數 target;
  3. 實現 Callable 接口,實現 call() 方法,然后通過 FutureTask 包裝器來創(chuàng)建 Thread 線程;
  4. 通過 ThreadPoolExecutor 創(chuàng)建線程池,并從線程池中獲取線程用于執(zhí)行任務;

繼承Thread類

創(chuàng)建步驟:

  1. 定義類繼承Thread;
  2. 重寫Thread類中的run方法;
  3. 實例化線程對象;
  4. 調用線程的start方法開啟線程;

代碼:

package com.scg.springcloudordercenter.controller;
 
// 1.繼承Thread類
public class ThreadDemo extends Thread{
 
    private int ticket=20;
 
    // 2.重寫run 方法
    public void run(){
        for(int i=0;i<20;i++){
 
            if(this.ticket>0){
                System.out.println("剩余票數=="+ticket--);
            }
        }
 
    }
}
 
class ThreadTest {
    public static void main(String[] args) {
        // 3.實例化線程對象
        ThreadDemo md = new ThreadDemo() ;
        // 4.調用start()開啟線程
        md.start();
    }
}
 
 

通過實現 Runnable 接口

創(chuàng)建步驟:

  1. 實現Runnable接口;
  2. 重寫Run()方法;
  3. 實例化實現類;
  4. 將實例化線程類轉化為線程對象;
  5. 開啟線程 調用start()方法;

代碼

package com.scg.springcloudordercenter.controller;
 
 
// 1.實現Runnable類
public class RunnableDemo implements Runnable{
 
    private int ticket=20;
 
    // 2.重寫run 方法
    public void run(){
        for(int i=0;i<20;i++){
 
            if(this.ticket>0){
                System.out.println("剩余票數=="+ticket--);
            }
        }
 
    }
}
 
class RunnableTest {
    public static void main(String[] args) {
        // 3.實例化實現類
        RunnableDemo rd = new RunnableDemo() ;
        // 4.將實例化實現類轉化為線程對象
        Thread thread = new Thread(rd);
        // 5.開啟線程
        thread.start();
    }
}
 
 
實現 Runnable 接口比繼承 Thread 類所具有的優(yōu)勢主要有:
① 可以避免 JAVA 中單繼承的限制;
② 線程池只能放入實現 Runable 或 Callable類線程,不能直接放入繼承 Thread 的類
③ 代碼可以被多個線程共享,代碼和數據獨立,適合多個相同的程序代碼的線程去處理同一個資源的情況

實現Callable接口

實現步驟

1、定義一個線程任務類實現Callable接口,聲明線程執(zhí)行的結果類型。

2、重寫線程任務類的call()方法,這個方法可以直接返回執(zhí)行的結果。

3、創(chuàng)建一個Callable的線程任務對象。

4、把Callable的線程任務對象包裝成一個未來任務對象。

5、把未來任務對象包裝成線程對象。

6、調用線程start()方法,啟動線程。

7、獲取線程執(zhí)行結果。

代碼:

/**
 * @author gf
 * @date 2023/2/22
 */
// 1、定義一個線程任務類實現Callable接口,聲明線程執(zhí)行的結果類型。
public class CallableTicket implements Callable<Object > {
 
    private int ticket=20;
 
    // 2、重寫線程任務類的call()方法,這個方法可以直接返回執(zhí)行的結果。
    @Override
    public Object  call() throws Exception {
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
            if (i % 2 == 0) {
                sum += i;
            }
        }
        return sum;
    }
 
}
package com.scg.springcloudordercenter.controller;
 
import java.util.concurrent.FutureTask;
 
/**
 * @author gf
 * @date 2023/2/22
 */
public class CallableMain {
 
    public static void main(String[] args) {
 
        // 3、創(chuàng)建一個Callable的線程任務對象。
        CallableTicket callableTicket = new CallableTicket();
 
        // 4、把Callable的線程任務對象包裝成一個未來任務對象。
        FutureTask futureTask = new FutureTask(callableTicket);
 
        // 5、把未來任務對象包裝成線程對象。
        Thread thread = new Thread(futureTask);
 
        // 6、調用線程start()方法,啟動線程。
        thread.start();
 
        // 7、獲取線程執(zhí)行結果。如果此時獲取結果的任務還未執(zhí)行完成,會讓出CPU,直至任務執(zhí)行完成才獲取結果。
        try {
            //6.獲取Callable中call方法的返回值
            //get()返回值即為FutureTask構造器參數Callable實現類重寫的call()方法返回值。
            Object sum = futureTask.get();
            System.out.println("總和為:"+sum);
        } catch (Exception e) {
            e.printStackTrace();
        }
 
 
    }
}

優(yōu)點:

與使用Runnable相比,Callable功能更強大

  • 相比run方法,可以有返回值。
  • 方法可以拋異常。
  • 支持泛型的返回值。
  • 需要借助FutureTask類,比如獲取返回結果。

Future接口

  • 可以對具體Runnable、Callable任務的執(zhí)行結果進行取消、查詢是否完成、獲取結果等。
  • FutureTask是Future接口的唯一實現類。
  • FutureTask同時實現了Runable,Future接口。它既可以作為Runnable被線程執(zhí)行,又可以作為Future得到Callable的返回值

使用線程池

通過Executors創(chuàng)建

它提供了四種線程池:

  1. newCachedThreadPool創(chuàng)建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
  2. newFixedThreadPool 創(chuàng)建一個定長線程池,可控制線程最大并發(fā)數,超出的線程會在隊列中等待。
  3. newScheduledThreadPool 創(chuàng)建一個定長線程池,支持定時及周期性任務執(zhí)行。
  4. newSingleThreadExecutor 創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務,保證所有任務按照指定順序(FIFO, LIFO, 優(yōu)先級)執(zhí)行。
public class Demo01 {
    public static void main(String[] args) {
        //ExecutorService threadPool = Executors.newSingleThreadExecutor(); //創(chuàng)建單個線程
        //ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);//創(chuàng)建一個固定大小的線程池
        //ExecutorService threadPool = Executors.newFixedThreadPool(5); //創(chuàng)建一個固定大小的線程池
        ExecutorService threadPool = Executors.newCachedThreadPool(); //創(chuàng)建大小可伸縮的線程池
 
        try {
            for (int i = 0; i < 30; i++) {
                //使用線程池來創(chuàng)建線程
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+"ok");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown(); //線程池使用完畢后需要關閉
        }
 
    }
}

注意:不建議使用這種方法創(chuàng)建線程池。因為newFixedThreadPool 和newSingleThreadExecutor允許的最大請求隊列長度為Integer.MAX_VALUE,可能會堆積大量的請求,從而導致OOM。newCachedThreadPoo和newScheduledThreadPool允許的創(chuàng)建線程的最大數量為Integer.MAX_VALUE,,從而導致OOM。

通過ThreadPoolExecutor創(chuàng)建

ThreadPoolExecutor有7個核心參數

  1. ThreadPoolExecutor(int corePoolSize, //核心線程池大小,始終存在
  2. int maximumPoolSize, //最大線程數
  3. long keepAliveTime, //空閑線程等待時間,超時則銷毀
  4. TimeUnit unit, //時間單位
  5. BlockingQueue<Runnable> workQueue, //等待阻塞隊列
  6. ThreadFactory threadFactory, //線程工廠
  7. RejectedExecutionHandler handler) //線程拒絕策略

其最后一個參數拒絕策略共有四種:

  • new ThreadPoolExecutor.AbortPolicy():達到最大承載量,不再處理,并且拋出異常
  • new ThreadPoolExecutor.CallerRunsPolicy():達到最大承載量,從哪來的去哪里
  • new ThreadPoolExecutor.DiscardPolicy():達到最大承載量,丟掉任務,但不拋出異常
  • new ThreadPoolExecutor.DiscardOldestPolicy():達到最大承載量,嘗試與最早執(zhí)行的線程去競爭,不拋出異常
public class Demo02 {
    public static void main(String[] args) {
        //new ThreadPoolExecutor.AbortPolicy():達到最大承載量,不再處理,并且拋出異常
        //new ThreadPoolExecutor.CallerRunsPolicy():達到最大承載量,從哪來的去哪里
        //new ThreadPoolExecutor.DiscardPolicy():達到最大承載量,丟掉任務,但不拋出異常
        //new ThreadPoolExecutor.DiscardOldestPolicy():達到最大承載量,嘗試與最早執(zhí)行的線程去競爭,不拋出異常
 
        //最大線程池大小該如何定義
        //1.cpu密集型,邏輯處理器個數
        //2.io密集型 > 判斷程序十分耗IO的線程,最大線程池大小應該比這個大
        int maxPools= Runtime.getRuntime().availableProcessors();
        System.out.println(maxPools);
 
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                2,
                maxPools,
                3,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );
 
        try {
            for (int i = 0; i < 10; i++) {
                //使用線程池來創(chuàng)建線程
                //最大承載:maximumPoolSize+workQueue,超過執(zhí)行拒絕策略
                threadPool.execute(()->{
                    System.out.println(Thread.currentThread().getName()+" ok");
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            threadPool.shutdown(); //線程池使用完畢后需要關閉
        }
 
    }
}

使用線程池的優(yōu)點;

1.減少資源的消耗。重復利用已經創(chuàng)建的線程,避免頻繁的創(chuàng)造和銷毀線程,減少消耗。

2.提高響應速度。當執(zhí)行任務時,不需要去創(chuàng)建線程再來執(zhí)行,只要調動現有的線程來執(zhí)行即可。

3.提高了線程的管理性。線程是稀缺資源,使用線程池可以進行統一的分配、調優(yōu)和監(jiān)控。

到此這篇關于Java中創(chuàng)建線程的四種方法解析的文章就介紹到這了,更多相關Java創(chuàng)建線程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Maven+oracle+SSM搭建簡單項目的方法

    Maven+oracle+SSM搭建簡單項目的方法

    本篇文章主要介紹了Maven+oracle+SSM搭建簡單項目的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • Java日常練習題,每天進步一點點(51)

    Java日常練習題,每天進步一點點(51)

    下面小編就為大家?guī)硪黄狫ava基礎的幾道練習題(分享)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧,希望可以幫到你
    2021-08-08
  • 一文詳解Spring?security框架的使用

    一文詳解Spring?security框架的使用

    Spring?Security是一個基于Spring框架的安全認證和授權框架,它提供了一套全面的安全解決方案,可以在Web應用、移動應用和Web服務等不同場景下使用。本文就來詳細聊聊它的使用吧
    2023-03-03
  • 一文教你掌握Java如何實現判空

    一文教你掌握Java如何實現判空

    實際項目中我們會有很多地方需要判空校驗,如果不做判空校驗則可能產生NullPointerException異常。所以本文小編為大家整理了Java中幾個常見的判空方法,希望對大家有所幫助
    2023-04-04
  • Java利用httpclient通過get、post方式調用https接口的方法

    Java利用httpclient通過get、post方式調用https接口的方法

    這篇文章主要介紹了Java利用httpclient通過get、post方式調用https接口的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • Kafka是什么及如何使用SpringBoot對接Kafka(最新推薦)

    Kafka是什么及如何使用SpringBoot對接Kafka(最新推薦)

    這篇文章主要介紹了Kafka是什么,以及如何使用SpringBoot對接Kafka,今天我們通過一個Demo講解了在SpringBoot中如何對接Kafka,也介紹了下關鍵類?KafkaTemplate,需要的朋友可以參考下
    2023-11-11
  • MyBatis還是JPA?終于有答案了

    MyBatis還是JPA?終于有答案了

    這篇文章主要介紹了MyBatis還是JPA,中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • 使用maven項目pom.xml文件配置打包功能和靜態(tài)資源文件自帶版本號功能

    使用maven項目pom.xml文件配置打包功能和靜態(tài)資源文件自帶版本號功能

    在Maven項目中,通過pom.xml文件配置打包功能,可以控制構建過程,生成可部署的包,同時,為了緩存控制與版本更新,可以在打包時給靜態(tài)資源文件如JS、CSS添加版本號,這通常通過插件如maven-resources-plugin實現
    2024-09-09
  • Java中List對象集合按對象中某字段進行排序舉例

    Java中List對象集合按對象中某字段進行排序舉例

    這篇文章主要給大家介紹了關于Java中List對象集合按對象中某字段進行排序的相關資料,我們在日常開發(fā)中也經常會用到排序算法,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-07-07
  • Java Lambda 表達式詳解及示例代碼

    Java Lambda 表達式詳解及示例代碼

    本文主要介紹Java Lambda 表達式的知識,這里整理了相關資料,JavaLambda 是Java8 引入的新功能,有興趣的小伙伴可以參考下
    2016-09-09

最新評論