欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java不同線程解讀以及線程池的使用方式

 更新時間:2024年08月22日 10:58:12   作者:200.OK  
這篇文章主要介紹了java不同線程解讀以及線程池的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

java不同線程解讀以及線程池的使用

線程池子類比一個水池,而每一個線程,都好比水池的水。因此,水池多大,看系統(tǒng)硬件配置。線程池主要為了并發(fā),高效處理任務(wù)。而異步處理任務(wù),可以有效提高處理任務(wù)的吞吐量。

線程池的常見應(yīng)用場景

處理大量而短小的請求,請求數(shù)量很大,每一個請求開啟一個線程,在請求完畢之后再對線程進行銷毀,這樣創(chuàng)建和銷毀線程所消耗的時間往往比任務(wù)本身所需消耗的資源要大得多。

線程池做到線程復(fù)用,不需要頻繁的創(chuàng)建和銷毀線程,線程池中的線程一直存在于線程池中,線程從任務(wù)隊列中取得任務(wù)來執(zhí)行。而且這樣做的另一個好處有,通過適當(dāng)?shù)卣{(diào)整線程池中的線程數(shù)目,也就是當(dāng)請求的數(shù)目超過某個閾值時,就強制其它任何新到的請求一直等待,直到獲得一個線程來處理為止,從而可以防止資源不足。

線程池是什么?

線程池用于多線程處理中,它可以根據(jù)系統(tǒng)的情況,可以控制線程執(zhí)行的數(shù)量,優(yōu)化運行效果。線程池做的工作主要是控制運行的線程的數(shù)量,處理過程中將任務(wù)放入隊列,然后在線程創(chuàng)建后啟動這些任務(wù),如果線程數(shù)量超過了最大數(shù)量超出數(shù)量的線程排隊等候,等其它線程執(zhí)行完畢,再從隊列中取出任務(wù)來執(zhí)行。

線程池的作用

創(chuàng)建對象和銷毀對象是非常消耗時間和資源的。因此想要最小化這種消耗的一種思想就是『池化資源』,通過重用線程池中的資源來減少創(chuàng)建和銷毀線程所需要耗費的時間和資源。

線程池的一個作用是創(chuàng)建和銷毀線程的次數(shù),每個工作線程可以多次使用;另一個作用是可根據(jù)系統(tǒng)情況調(diào)整執(zhí)行的線程數(shù)量,防止消耗過多內(nèi)存。另外,通過線程池,能有效的控制線程的最大并發(fā)數(shù),提高系統(tǒng)資源利用率,同時避免過多的資源競爭,避免堵塞。

線程池的優(yōu)點總結(jié)如下幾個方面:

  • 線程復(fù)用
  • 控制最大并發(fā)數(shù)
  • 管理線程

線程池組成

  • 線程池管理器:用于創(chuàng)建并管理線程池
  • 工作線程:線程池中的線程
  • 任務(wù)接口:每個任務(wù)必須實現(xiàn)的接口,用于工作線程調(diào)度其運行
  • 任務(wù)隊列:用于存放待處理的任務(wù),提供一種緩沖機制

1、Async 和 @Async 很關(guān)鍵

兩個注解很關(guān)鍵:

  • @EnableAsync 啟用基于異步方法的執(zhí)行
  • @Async 這注解的函數(shù)會被異步處理

2、Thread和Runnable

Thread可以創(chuàng)建線程,但是線程使用完之后需要對線程資源進行銷毀回收,消耗資源,且容易造成線程上下文切換(操作系統(tǒng)核心對CPU上對進程或者線程進行切換)問題,線程管理不當(dāng)容易資源耗盡,不建議使用。、

一個類實現(xiàn) Runnable 接口可以將該類的實例傳遞給一個 Thread 對象并啟動一個新線程,這個新線程就會執(zhí)行該類中 void run() 方法中所定義的邏輯。

3、數(shù)據(jù)類型—線程安全

如果有多線程共享數(shù)據(jù)的方式,要牢記各種使用場景的線程安全數(shù)據(jù)類型。

  • (1)、AtomicInteger 原子int整型;
  • (2)、AtomicLong 原子long整型;
  • (3)、AtomicBoolean 原子boolean;
  • (4)、List 這三種都是線程安全型:
①List<T> vector = new Vector<>();
②<T> listSyn = Collections.synchronizedList(new ArrayList<>()); 
③List<T> copyList = new CopyOnWriteArrayList<>();

4、@Configuration配置類和 @Bean將實例對象交給IOC容器

5、ThreadPoolExecutor 和 ThreadPoolTaskExecutor

兩種線程池方式,本質(zhì)上一樣,ThreadPoolTaskExecutor(我使用的) 源碼上是在 ThreadPoolExecutor 上再加了一層包裝,為了更方便在spring框架中使用。

  • 配置類: 可以確保異步執(zhí)行配置對應(yīng)用中的所有 bean 都生效。
  • 啟動類: 啟動類上整個應(yīng)用中啟用異步
  • 推薦: 針對應(yīng)用中的不同部分提供不同的異步執(zhí)行策略,或者只需要特定的一部分 bean 具備異步執(zhí)行能力,放配置類上。如果整個應(yīng)用都需要異步支持,放置在啟動類。

使用@Bean(“beanName”)定義線程池 然后在@Async(“beanName”)中引用指定的線程池

@EnableAsync 用于啟用整個應(yīng)用程序的異步處理功能,包括所有通過 @Async 注解標(biāo)記的方法。它不負責(zé)配置底層線程池。

ThreadPoolTaskExecutor Bean 配置則是用于配置具體的線程池實例,這個線程池會被 @Async 方法所使用。

如果你在配置類中同時使用了 @EnableAsync 注解和自定義的 ThreadPoolTaskExecutor Bean 配置,Spring 將會使用你配置的線程池執(zhí)行異步方法。如果你只使用 @EnableAsync,Spring 將會使用默認(rèn)的線程池配置。

注意

  • 1、除了要在方法上加@Async注解,還需要在啟動類加注解@EnableAsync啟動多線程注解,@Async就會對標(biāo)注的方法開啟異步多線程調(diào)用,注意,這個方法的類一定要交給Spring容器來管理。
  • 2、法一定要從另一個類中調(diào)用,也就是從類的外部調(diào)用,類的內(nèi)部調(diào)用是無效的,因為@Transactional和@Async注解的實現(xiàn)都是基于Spring的AOP,而AOP的實現(xiàn)是基于動態(tài)代理模式實現(xiàn)的。那么注解失效的原因就很明顯了,有可能因為調(diào)用方法的是對象本身而不是代理對象,因為沒有經(jīng)過Spring容器
  • 3、異步方法使用注解@Async的返回值只能為void或者Future
  • 4、方法必須是public方法

定義線程池的配置

package com.test.wll.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

@EnableAsync//或者加在app類上,此處不加需要在啟動類上加
@Configuration 
public class ThreadPoolTaskConfig {

    @Bean("threadPoolRedisTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolRedisTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //線程池創(chuàng)建的核心線程數(shù),線程池維護線程的最少數(shù)量,即使沒有任務(wù)需要執(zhí)行,也會一直存活
        executor.setCorePoolSize(8);
        //如果設(shè)置allowCoreThreadTimeout=true(默認(rèn)false)時,核心線程會超時關(guān)閉
        //executor.setAllowCoreThreadTimeOut(true);
        //阻塞隊列 當(dāng)核心線程數(shù)達到最大時,新任務(wù)會放在隊列中排隊等待執(zhí)行
        executor.setQueueCapacity(124);
        //最大線程池數(shù)量,當(dāng)線程數(shù)>=corePoolSize,且任務(wù)隊列已滿時。線程池會創(chuàng)建新線程來處理任
        //任務(wù)隊列已滿時, 且當(dāng)線程數(shù)=maxPoolSize,,線程池會拒絕處理任務(wù)而拋出異常
        executor.setMaxPoolSize(64);
        //當(dāng)線程空閑時間達到keepAliveTime時,線程會退出,直到線程數(shù)量=corePoolSize
        //允許線程空閑時間30秒,當(dāng)maxPoolSize的線程在空閑時間到達的時候銷毀
        //如果allowCoreThreadTimeout=true,則會直到線程數(shù)量=0
        executor.setKeepAliveSeconds(30);
        //spring 提供的 ThreadPoolTaskExecutor 線程池,是有setThreadNamePrefix() 方法的。
        //jdk 提供的ThreadPoolExecutor 線程池是沒有 setThreadNamePrefix() 方法的
        executor.setThreadNamePrefix("threadPoolRedisTaskExecutor");
        // rejection-policy:拒絕策略:當(dāng)線程數(shù)已經(jīng)達到maxSize的時候,如何處理新任務(wù)
        // CallerRunsPolicy():交由調(diào)用方線程運行,比如 main 線程;如果添加到線程池失敗,那么主線程會自己去執(zhí)行該任務(wù),不會等待線程池中的線程去執(zhí)行
        // AbortPolicy():該策略是線程池的默認(rèn)策略,如果線程池隊列滿了丟掉這個任務(wù)并且拋出RejectedExecutionException異常。
        // DiscardPolicy():如果線程池隊列滿了,會直接丟掉這個任務(wù)并且不會有任何異常
        // DiscardOldestPolicy():丟棄隊列中最老的任務(wù),隊列滿了,會將最早進入隊列的任務(wù)刪掉騰出空間,再嘗試加入隊列
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
        executor.initialize();
        return executor;
    }
}
}
        //最大線程數(shù)
        executor.setMaxPoolSize(maxPoolSize);
        //核心線程數(shù)
        executor.setCorePoolSize(corePoolSize);
        //任務(wù)隊列的大小
        executor.setQueueCapacity(queueCapacity);
        //線程前綴名
        executor.setThreadNamePrefix(namePrefix);
        //線程存活時間
        executor.setKeepAliveSeconds(keepAliveSeconds);
    //此處的名字要與線程池的名字一致,清晰的命名可以清晰的了解哪個線程報錯
    @Async("threadName")
    @GetMapping("/方法名字")
    public Result<String> test() {
}

6、拒絕策略

rejectedExectutionHandler參數(shù)字段用于配置絕策略,常用拒絕策略如下

  • AbortPolicy:用于被拒絕任務(wù)的處理程序,它將拋出RejectedExecutionException
  • CallerRunsPolicy:用于被拒絕任務(wù)的處理程序,直接在execute方法的調(diào)用線程中運行被拒絕的任務(wù)。
  • DiscardOldestPolicy:用于被拒絕任務(wù)的處理程序,放棄最舊的未處理請求,然后重試execute。
  • DiscardPolicy:用于被拒絕任務(wù)的處理程序,默認(rèn)情況下它將丟棄被拒絕的任務(wù)。

7、線程池處理流程

線程池的工作流程(必知必會)?

這個問題回答的時候,最好用講故事的方式進行。 假如核心線程數(shù)是5,最大線程數(shù)是10,阻塞隊列也是10

  • 1)有新任務(wù)來的時候,將先使用核心線程執(zhí)行;
  • 2)當(dāng)任務(wù)數(shù)達到5個的時候,第6個任務(wù)開始排隊;
  • 3)當(dāng)任務(wù)數(shù)達到15個的時候,第16個任務(wù)將開啟新的線程執(zhí)行,也就是第6個線程
  • 4)當(dāng)任務(wù)數(shù)達到20個的時候,線程池滿了,如果有第21個任務(wù),將執(zhí)行拒絕策略

8、 Hutool 的ThreadUtil.execute

execute 方法是通過 GlobalThreadPool 來執(zhí)行任務(wù)的,而 GlobalThreadPool 在 Hutool 中是一個全局的線程池。

它會使用默認(rèn)的配置來初始化線程池,這些默認(rèn)配置在 Hutool 內(nèi)部已經(jīng)設(shè)定好了,因此在使用 execute 方法時不需要手動指定核心池大小和最大池大小。

這種方法適合簡單的任務(wù)執(zhí)行,如果需要更靈活的線程池配置(比如自定義線程數(shù)、隊列類型等),可以考慮使用 newExecutor 等方法手動創(chuàng)建線程池,并進行更詳細的配置。

spring的 ThreadPoolTaskExecutor

  • 優(yōu)點: Spring 的 ThreadPoolTaskExecutor 是 Spring 框架提供的一個線程池實現(xiàn),它提供了很多配置選項,允許你更加靈活地定制線程池的行為,比如核心線程數(shù)、最大線程數(shù)、隊列容量、線程存活時間等。
  • 適用情況: 適合在 Spring 環(huán)境中使用,對于基于 Spring 的項目,使用這種方式可以充分利用 Spring 提供的特性和管理能力,例如可以方便地集成到 Spring 的任務(wù)調(diào)度中

Hutool ThreadUtil

  • 優(yōu)點: Hutool 提供的 ThreadUtil 類是一個簡化了的工具類,提供了一些靜態(tài)方法來方便地創(chuàng)建線程池和執(zhí)行任務(wù)。它是一個輕量級的工具庫,適合在一般的 Java 程序中使用,不依賴于 Spring 框架。
  • 適用情況: 適合非 Spring 項目或者不需要集成到 Spring 容器管理的場景。如果你不需要太多的線程池配置選項,而只是簡單地執(zhí)行任務(wù),使用 ThreadUtilexecute 方法會更加便捷。

常見線程池

  • 1)定長線程池(FixedThreadPool)
  • 2)定時線程池(ScheduledThreadPool)
  • 3)可緩存線程池(CachedThreadPool)
  • 4)單線程化線程池(SingleThreadExecutor)

核心概念:這四個線程池的本質(zhì)都是ThreadPoolExecutor對象(看源碼)

不同點在于:

  • 1)FixedThreadPool:只有核心線程,線程數(shù)量固定,執(zhí)行完立即回收,任務(wù)隊列為鏈表結(jié)構(gòu)的有界隊列。
  • 2)ScheduledThreadPool:核心線程數(shù)量固定,非核心線程數(shù)量無限,執(zhí)行完閑置 10ms 后回收,任務(wù)隊列為延時阻塞隊列。
  • 3)CachedThreadPool:無核心線程,非核心線程數(shù)量無限,執(zhí)行完閑置 60s 后回收,任務(wù)隊列為不存儲元素的阻塞隊列。
  • 4)SingleThreadExecutor:只有 1 個核心線程,無非核心線程,執(zhí)行完立即回收,任務(wù)隊列為鏈表結(jié)構(gòu)的有界隊列

線程池的主要參數(shù)有哪些(必知必會)?

  • 1)corePoolSize(必需):核心線程數(shù)。默認(rèn)情況下,核心線程會一直存活,但是當(dāng)將 allowCoreThreadTimeout 設(shè)置為 true 時,核心線程也會超時回收。
  • 2)maximumPoolSize(必需):線程池所能容納的最大線程數(shù)。當(dāng)活躍線程數(shù)達到該數(shù)值后,后續(xù)的新任務(wù)將會阻塞。
  • 3)keepAliveTime(必需):線程閑置超時時長。如果超過該時長,非核心線程就會被回收。如果將 allowCoreThreadTimeout 設(shè)置為 true 時,核心線程也會超時回收。
  • 4)unit(必需):指定 keepAliveTime 參數(shù)的時間單位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)。
  • 5)workQueue(必需):任務(wù)隊列。通過線程池的 execute() 方法提交的 Runnable 對象將存儲在該參數(shù)中。其采用阻塞隊列實現(xiàn)。
  • 6)threadFactory(可選):線程工廠。用于指定為線程池創(chuàng)建新線程的方式。
  • 7)handler(可選):拒絕策略。當(dāng)達到最大線程數(shù)時需要執(zhí)行的飽和策略。

線程池的工作流程(必知必會)?

這個問題回答的時候,最好用講故事的方式進行。 假如核心線程數(shù)是5,最大線程數(shù)是10,阻塞隊列也是10

  • 1)有新任務(wù)來的時候,將先使用核心線程執(zhí)行;
  • 2)當(dāng)任務(wù)數(shù)達到5個的時候,第6個任務(wù)開始排隊;
  • 3)當(dāng)任務(wù)數(shù)達到15個的時候,第16個任務(wù)將開啟新的線程執(zhí)行,也就是第6個線程
  • 4)當(dāng)任務(wù)數(shù)達到20個的時候,線程池滿了,如果有第21個任務(wù),將執(zhí)行拒絕策略

線程安全

函數(shù)、函數(shù)庫在并發(fā)環(huán)境中被調(diào)用時,能夠正確地處理多個線程之間的共享變量,使程序功能正確完成。

  • 并發(fā):(由cpu分配時間片,看似像同時干多個事情實際是由不同的cpu時間片干)任務(wù)執(zhí)行時間比調(diào)度頻率長,會導(dǎo)致任務(wù)堆積,任務(wù)完成后,才能開始下一個任務(wù),可能會造成任務(wù)被阻塞,直到有空閑線程可用。當(dāng)任務(wù)執(zhí)行時間比調(diào)度頻率長時,會出現(xiàn)并發(fā)問題,線程池中的線程會被任務(wù)堵塞,直到前一個任務(wù)執(zhí)行完成。
  • 并行:當(dāng)系統(tǒng)有一個以上CPU時,當(dāng)一個CPU執(zhí)行一個進程時,另一個CPU可以執(zhí)行另一個進程,兩個進程互不搶占CPU資源,可以同時進行,這種方式我們稱之為并行(Parallel)。

eg:并發(fā)是兩個隊伍交替使用一臺咖啡機。并行是兩個隊伍同時使用兩臺咖啡機。

  • 線程和進程:下載為進程,下載的多個視頻為線程,共享線程資源
  • 共享變量:指的是多個線程都可以操作的變量

保存在方法區(qū)中的變量就是Java中的共享變量

堆中存放new出來的對象,(包括實例變量); 棧中存放正在調(diào)用的方法中的局部變量 (包括方法的參數(shù)); 方法區(qū)中存儲.class 字節(jié)碼 文件(包括 靜態(tài)變量 、靜態(tài)方法)

public class Variables {
    // 類變量  共享變量
    private static int a;
    //成員變量  共享變量
    private int b;
    //局部變量  c和d 非共享變量
    public void test(int c){
        int d;
    }
}
//多線程場景,對于變量a和b的操作是需要考慮線程安全的,而對于線程c和d的操作是不需要考慮線程安全的。

線程不安全

多線程并發(fā)執(zhí)行某個代碼時,產(chǎn)生了邏輯上的錯誤,結(jié)果和預(yù)期值不相同 線程安全是指多線程執(zhí)行時沒有產(chǎn)生邏輯錯誤,結(jié)果和預(yù)期值相同

//開啟了兩個線程,每個線程執(zhí)行1000次循環(huán),循環(huán)中對count進行加1操作。等待兩個線程都執(zhí)行完成后,打印count的值。
public class Test {
     private  static  int count;
    private static class Thread1 extends Thread {
        public void run() {
            for (int i = 0; i < 1000; i++) {
                count ++;
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread1  t1 = new Thread1();
        Thread1  t2 = new Thread1();
        t1.start();
        t2.start();
        //main主線程內(nèi)調(diào)用join()方法:休眠主線程,等待t1、t2線程執(zhí)行完畢主線程再繼續(xù),即最后輸出count值
        t1.join();
        t2.join();
        System.out.println(count);
    }
}

輸出結(jié)果應(yīng)該是2000但是不有時候1996

count++的指令在實際執(zhí)行的過程中不是原子性的,而是要分為讀、改、寫三步來進行;即先從內(nèi)存中讀出count的值,然后執(zhí)行+1操作,再將結(jié)果寫回內(nèi)存中,如下圖所示。

上圖中線程1執(zhí)行了兩次自加操作,而線程2執(zhí)行了一次自加操作,但是count卻從6變成了8,只加了2。

我們看一下為什么會出現(xiàn)這種情況。當(dāng)線程1讀取count的值為6完成后,此時切換到了線程2執(zhí)行,線程2同樣讀取到了count的值為6,而后進行改和寫操作,count的值變?yōu)榱?;此時線程又切回了線程1,但是線程1中count的值依然是線程2修改前的6,這就是問題所在!即線程2修改了count的值,但是這種修改對線程1不可見,導(dǎo)致了程序出現(xiàn)了線程不安全的問題,沒有符合我們預(yù)期的邏輯。

導(dǎo)致線程不安全的原因

主要有三點:

  • 不滿足原子性:一個或者多個操作在 CPU 執(zhí)行的過程中被中斷,當(dāng) cpu 執(zhí)行一個線程過程時,調(diào)度器可能調(diào)走CPU,去執(zhí)行另一個線程,此線程的操作可能還沒有結(jié)束;(synchronized鎖解決)
  • 不滿足可見性:一個線程對共享變量的修改,另外一個線程不能立刻看到
  • 不滿足有序性:程序執(zhí)行的順序沒有按照代碼的先后順序執(zhí)行三、怎樣解決線程不安全

Java中的原子操作包括:

  • 除long和double之外的基本類型的賦值操作
  • 所有引用reference的賦值操作
  • java.concurrent.Atomic.* 包中所有類的一切操作

可見性是指當(dāng)多個線程訪問同一個變量時,一個線程修改了這個變量的值,其他線程能夠立即看得到修改的值。

volatile關(guān)鍵字來保證可見性。當(dāng)一個共享變量被volatile修飾時,它會保證修改的值會立即被更新到主存,當(dāng)有其他線程需要讀取時,它會去內(nèi)存中讀取新值。而普通的共享變量不能保證可見性,因為普通共享變量被修改之后,什么時候被寫入主存是不確定的,當(dāng)其他線程去讀取時,此時內(nèi)存中可能還是原來的舊值,因此無法保證可見性。另外,通過synchronized和Lock也能夠保證可見性,synchronized和Lock能保證同一時刻只有一個線程獲取鎖然后執(zhí)行同步代碼,并且在釋放鎖之前會將對變量的修改刷新到主存當(dāng)中。因此可以保證可見性。

volatile關(guān)鍵字來保證一定的“有序性”。另外可以通過synchronized和Lock來保證有序性,很顯然,synchronized和Lock保證每個時刻是有一個線程執(zhí)行同步代碼,相當(dāng)于是讓線程順序執(zhí)行同步代碼,自然就保證了有序性。另外,Java內(nèi)存模型具備一些先天的“有序性”,即不需要通過任何手段就能夠得到保證的有序性,這個通常也稱為 happens-before 原則。如果兩個操作的執(zhí)行次序無法從happens-before原則推導(dǎo)出來,那么它們就不能保證它們的有序性,虛擬機可以隨意地對它們進行重排序。

補充:happens-before原則(先行發(fā)生原則)

  • 程序次序規(guī)則:一個線程內(nèi),按照代碼順序,書寫在前面的操作先行發(fā)生于書寫在后面的操作。
  • 鎖定規(guī)則:一個unLock操作先行發(fā)生于后面對同一個鎖額lock操作。
  • volatile變量規(guī)則:對一個變量的寫操作先行發(fā)生于后面對這個變量的讀操作。
  • 傳遞規(guī)則:如果操作A先行發(fā)生于操作B,而操作B又先行發(fā)生于操作C,則可以得出操作A先行發(fā)生于操作C。
  • 線程啟動規(guī)則:Thread對象的start()方法先行發(fā)生于此線程的每個一個動作。
  • 線程中斷規(guī)則:對線程interrupt()方法的調(diào)用先行發(fā)生于被中斷線程的代碼檢測到中斷事件的發(fā)生。
  • 線程終結(jié)規(guī)則:線程中所有的操作都先行發(fā)生于線程的終止檢測,我們可以通過Thread.join()方法結(jié)束、Thread.isAlive()的返回值手段檢測到線程已經(jīng)終止執(zhí)行。
  • 對象終結(jié)規(guī)則:一個對象的初始化完成先行發(fā)生于他的finalize()方法的開始。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot配置項目訪問路徑URL的根路徑方式

    SpringBoot配置項目訪問路徑URL的根路徑方式

    這篇文章主要介紹了SpringBoot配置項目訪問路徑URL的根路徑方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • MybatisPlus中的insert操作詳解

    MybatisPlus中的insert操作詳解

    這篇文章主要介紹了MybatisPlus中的insert操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Java中集合LinkedList的原理與使用方法

    Java中集合LinkedList的原理與使用方法

    這篇文章主要給大家介紹了關(guān)于Java中集合LinkedList的原理與使用方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • 解決maven打包排除類不生效maven-compiler-plugin問題

    解決maven打包排除類不生效maven-compiler-plugin問題

    總結(jié):在Spring Boot項目B中作為項目A的依賴時,排除啟動類不生效的原因是被其他類引用或父POM引入,解決方法是跳過test編譯或注釋掉@SpringBootTest(classes={BApplication.class})
    2024-11-11
  • 區(qū)分java中String+String和String+char

    區(qū)分java中String+String和String+char

    這篇文章主要向大家詳細區(qū)分了java中String+String和String+char,感興趣的小伙伴們可以參考一下
    2016-01-01
  • java9新特性Collection集合類的增強與優(yōu)化方法示例

    java9新特性Collection集合類的增強與優(yōu)化方法示例

    這篇文章主要為大家介紹了java9新特性Collection集合類的增強與優(yōu)化方法示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步
    2022-03-03
  • JavaSE異常Exception處理方法以及自定義

    JavaSE異常Exception處理方法以及自定義

    網(wǎng)絡(luò)異常exception是指在網(wǎng)絡(luò)通信過程中出現(xiàn)的異常情況,這些異常可能是由于網(wǎng)絡(luò)連接不穩(wěn)定、網(wǎng)絡(luò)故障、服務(wù)器故障、網(wǎng)絡(luò)擁堵等原因?qū)е碌?這篇文章主要給大家介紹了關(guān)于JavaSE異常Exception處理方法以及自定義的相關(guān)資料,需要的朋友可以參考下
    2024-07-07
  • SpringBoot+Docker+IDEA實現(xiàn)一鍵構(gòu)建+推送、運行、同鏡像多容器啟動

    SpringBoot+Docker+IDEA實現(xiàn)一鍵構(gòu)建+推送、運行、同鏡像多容器啟動

    這篇文章主要介紹了SpringBoot+Docker+IDEA實現(xiàn)一鍵構(gòu)建+推送、運行、同鏡像多容器啟動,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • Java字符串常量池示例詳解

    Java字符串常量池示例詳解

    作為最基礎(chǔ)的引用數(shù)據(jù)類型,Java設(shè)計者為 String 提供了字符串常量池以提高其性能,下面這篇文章主要給大家介紹了關(guān)于Java字符串常量池的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • activiti實現(xiàn)員工請假流程解析

    activiti實現(xiàn)員工請假流程解析

    這篇文章主要介紹了activiti實現(xiàn)員工請假流程解析,本文通過實例代碼圖文相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07

最新評論