最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

前言

在 Java 中,實(shí)現(xiàn)多線程的主要有以下四種

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

繼承Thread類

創(chuàng)建步驟:

  1. 定義類繼承Thread;
  2. 重寫Thread類中的run方法;
  3. 實(shí)例化線程對象;
  4. 調(diào)用線程的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("剩余票數(shù)=="+ticket--);
            }
        }
 
    }
}
 
class ThreadTest {
    public static void main(String[] args) {
        // 3.實(shí)例化線程對象
        ThreadDemo md = new ThreadDemo() ;
        // 4.調(diào)用start()開啟線程
        md.start();
    }
}
 
 

通過實(shí)現(xiàn) Runnable 接口

創(chuàng)建步驟:

  1. 實(shí)現(xiàn)Runnable接口;
  2. 重寫Run()方法;
  3. 實(shí)例化實(shí)現(xiàn)類;
  4. 將實(shí)例化線程類轉(zhuǎn)化為線程對象;
  5. 開啟線程 調(diào)用start()方法;

代碼

package com.scg.springcloudordercenter.controller;
 
 
// 1.實(shí)現(xiàn)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("剩余票數(shù)=="+ticket--);
            }
        }
 
    }
}
 
class RunnableTest {
    public static void main(String[] args) {
        // 3.實(shí)例化實(shí)現(xiàn)類
        RunnableDemo rd = new RunnableDemo() ;
        // 4.將實(shí)例化實(shí)現(xiàn)類轉(zhuǎn)化為線程對象
        Thread thread = new Thread(rd);
        // 5.開啟線程
        thread.start();
    }
}
 
 
實(shí)現(xiàn) Runnable 接口比繼承 Thread 類所具有的優(yōu)勢主要有:
① 可以避免 JAVA 中單繼承的限制;
② 線程池只能放入實(shí)現(xiàn) Runable 或 Callable類線程,不能直接放入繼承 Thread 的類
③ 代碼可以被多個線程共享,代碼和數(shù)據(jù)獨(dú)立,適合多個相同的程序代碼的線程去處理同一個資源的情況

實(shí)現(xiàn)Callable接口

實(shí)現(xiàn)步驟

1、定義一個線程任務(wù)類實(shí)現(xiàn)Callable接口,聲明線程執(zhí)行的結(jié)果類型。

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

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

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

5、把未來任務(wù)對象包裝成線程對象。

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

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

代碼:

/**
 * @author gf
 * @date 2023/2/22
 */
// 1、定義一個線程任務(wù)類實(shí)現(xiàn)Callable接口,聲明線程執(zhí)行的結(jié)果類型。
public class CallableTicket implements Callable<Object > {
 
    private int ticket=20;
 
    // 2、重寫線程任務(wù)類的call()方法,這個方法可以直接返回執(zhí)行的結(jié)果。
    @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的線程任務(wù)對象。
        CallableTicket callableTicket = new CallableTicket();
 
        // 4、把Callable的線程任務(wù)對象包裝成一個未來任務(wù)對象。
        FutureTask futureTask = new FutureTask(callableTicket);
 
        // 5、把未來任務(wù)對象包裝成線程對象。
        Thread thread = new Thread(futureTask);
 
        // 6、調(diào)用線程start()方法,啟動線程。
        thread.start();
 
        // 7、獲取線程執(zhí)行結(jié)果。如果此時獲取結(jié)果的任務(wù)還未執(zhí)行完成,會讓出CPU,直至任務(wù)執(zhí)行完成才獲取結(jié)果。
        try {
            //6.獲取Callable中call方法的返回值
            //get()返回值即為FutureTask構(gòu)造器參數(shù)Callable實(shí)現(xiàn)類重寫的call()方法返回值。
            Object sum = futureTask.get();
            System.out.println("總和為:"+sum);
        } catch (Exception e) {
            e.printStackTrace();
        }
 
 
    }
}

優(yōu)點(diǎn):

與使用Runnable相比,Callable功能更強(qiáng)大

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

Future接口

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

使用線程池

通過Executors創(chuàng)建

它提供了四種線程池:

  1. newCachedThreadPool創(chuàng)建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
  2. newFixedThreadPool 創(chuàng)建一個定長線程池,可控制線程最大并發(fā)數(shù),超出的線程會在隊列中等待。
  3. newScheduledThreadPool 創(chuàng)建一個定長線程池,支持定時及周期性任務(wù)執(zhí)行。
  4. newSingleThreadExecutor 創(chuàng)建一個單線程化的線程池,它只會用唯一的工作線程來執(zhí)行任務(wù),保證所有任務(wù)按照指定順序(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(); //線程池使用完畢后需要關(guān)閉
        }
 
    }
}

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

通過ThreadPoolExecutor創(chuàng)建

ThreadPoolExecutor有7個核心參數(shù)

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

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

  • new ThreadPoolExecutor.AbortPolicy():達(dá)到最大承載量,不再處理,并且拋出異常
  • new ThreadPoolExecutor.CallerRunsPolicy():達(dá)到最大承載量,從哪來的去哪里
  • new ThreadPoolExecutor.DiscardPolicy():達(dá)到最大承載量,丟掉任務(wù),但不拋出異常
  • new ThreadPoolExecutor.DiscardOldestPolicy():達(dá)到最大承載量,嘗試與最早執(zhí)行的線程去競爭,不拋出異常
public class Demo02 {
    public static void main(String[] args) {
        //new ThreadPoolExecutor.AbortPolicy():達(dá)到最大承載量,不再處理,并且拋出異常
        //new ThreadPoolExecutor.CallerRunsPolicy():達(dá)到最大承載量,從哪來的去哪里
        //new ThreadPoolExecutor.DiscardPolicy():達(dá)到最大承載量,丟掉任務(wù),但不拋出異常
        //new ThreadPoolExecutor.DiscardOldestPolicy():達(dá)到最大承載量,嘗試與最早執(zhí)行的線程去競爭,不拋出異常
 
        //最大線程池大小該如何定義
        //1.cpu密集型,邏輯處理器個數(shù)
        //2.io密集型 > 判斷程序十分耗IO的線程,最大線程池大小應(yīng)該比這個大
        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(); //線程池使用完畢后需要關(guān)閉
        }
 
    }
}

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

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

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

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

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

相關(guān)文章

  • IDEA入門級使用教程你居然還在用eclipse?

    IDEA入門級使用教程你居然還在用eclipse?

    上個月,idea的使用量超越eclipse的消息席卷了整個IT界,idea到底好在哪里呢?下面小編通過本文給大家詳細(xì)介紹下IDEA入門級使用教程,非常詳細(xì),感興趣的朋友一起看看吧
    2020-10-10
  • Java List集合方法及遍歷過程代碼解析

    Java List集合方法及遍歷過程代碼解析

    這篇文章主要介紹了Java List集合方法及遍歷過程代碼解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • 為何找不到Java 7中的警告

    為何找不到Java 7中的警告

    在本篇文章和里小編給大家整理的是關(guān)于Java 7中的警告的相關(guān)知識點(diǎn)內(nèi)容,有需要的朋友們可以參考下。
    2019-11-11
  • SpringSecurity認(rèn)證流程詳解

    SpringSecurity認(rèn)證流程詳解

    這篇文章主要介紹了SpringSecurity認(rèn)證流程詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Java命令行運(yùn)行錯誤之找不到或無法加載主類問題的解決方法

    Java命令行運(yùn)行錯誤之找不到或無法加載主類問題的解決方法

    這篇文章主要給大家介紹了關(guān)于Java命令行運(yùn)行錯誤之找不到或無法加載主類問題的解決方法,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-01-01
  • mybatis實(shí)現(xiàn)動態(tài)升降序的問題小結(jié)

    mybatis實(shí)現(xiàn)動態(tài)升降序的問題小結(jié)

    文章介紹了如何在MyBatis的XML文件中實(shí)現(xiàn)動態(tài)排序,使用$符號而不是#符號來引用變量,以避免SQL注入,同時,強(qiáng)調(diào)了在Java代碼中進(jìn)行防注入處理的重要性,感興趣的朋友一起看看吧
    2025-02-02
  • JDBC基礎(chǔ)教程

    JDBC基礎(chǔ)教程

    這篇文章主要介紹了JDBC基礎(chǔ)知識與操作技巧,講述原理與基本技巧的基礎(chǔ)上分析了安全問題與操作注意事項,非常具有實(shí)用價值,需要的朋友可以參考下
    2014-12-12
  • Java雜談之代碼重構(gòu)的方法多長才算長

    Java雜談之代碼重構(gòu)的方法多長才算長

    關(guān)于代碼重構(gòu)的理解:在不改變軟件系統(tǒng)/模塊所具備的功能特性的前提下,遵循/利用某種規(guī)則,使其內(nèi)部結(jié)構(gòu)趨于完善。其在軟件生命周期中的價值體現(xiàn)主要在于可維護(hù)性和可擴(kuò)展性
    2021-10-10
  • java實(shí)現(xiàn)fibonacci數(shù)列學(xué)習(xí)示例分享(斐波那契數(shù)列)

    java實(shí)現(xiàn)fibonacci數(shù)列學(xué)習(xí)示例分享(斐波那契數(shù)列)

    這篇文章主要介紹了fibonacci數(shù)列(斐波那契數(shù)列)示例,大家參考使用吧
    2014-01-01
  • 一文詳解Spring是怎么讀取配置Xml文件的

    一文詳解Spring是怎么讀取配置Xml文件的

    這篇文章主要介紹了一文詳解Spring是怎么讀取配置Xml文件的,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-08-08

最新評論

东乌珠穆沁旗| 宜章县| 平安县| 福安市| 通山县| 德安县| 聂拉木县| 延吉市| 景德镇市| 新沂市| 花莲县| 甘孜县| 新余市| 曲麻莱县| 万盛区| 孟村| 玉树县| 涡阳县| 光泽县| 宜昌市| 凯里市| 双柏县| 天柱县| 云龙县| 内江市| 凤城市| 天气| 思南县| 高邮市| 尖扎县| 田东县| 抚顺县| 青川县| 拉孜县| 乐亭县| 黎川县| 石台县| 登封市| 涟水县| 江城| 淳安县|