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

很多人竟然不知道Java線程池的創(chuàng)建方式有7種

 更新時(shí)間:2021年07月30日 08:56:18   作者:麒麟改bug  
本文主要介紹了很多人竟然不知道Java線程池的創(chuàng)建方式有7種,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

前言

根據(jù)摩爾定律所說(shuō):集成電路上可容納的晶體管數(shù)量每 18 個(gè)月翻一番,因此 CPU 上的晶體管數(shù)量會(huì)越來(lái)越多。

但隨著時(shí)間的推移,集成電路上可容納的晶體管數(shù)量已趨向飽和,摩爾定律也漸漸失效,因此多核 CPU 逐漸變?yōu)橹髁鳎c之相對(duì)應(yīng)的多線程編程也開(kāi)始變得普及和流行起來(lái),這當(dāng)然也是很久之前的事了,對(duì)于現(xiàn)在而言多線程編程已經(jīng)成為程序員必備的職業(yè)技能了,那接下來(lái)我們就來(lái)盤(pán)一盤(pán)“線程池”這個(gè)多線程編程中最重要的話題。

什么是線程池?

線程池(ThreadPool)是一種基于池化思想管理和使用線程的機(jī)制。它是將多個(gè)線程預(yù)先存儲(chǔ)在一個(gè)“池子”內(nèi),當(dāng)有任務(wù)出現(xiàn)時(shí)可以避免重新創(chuàng)建和銷(xiāo)毀線程所帶來(lái)性能開(kāi)銷(xiāo),只需要從“池子”內(nèi)取出相應(yīng)的線程執(zhí)行對(duì)應(yīng)的任務(wù)即可。

池化思想在計(jì)算機(jī)的應(yīng)用也比較廣泛,比如以下這些:

  • 內(nèi)存池(Memory Pooling):預(yù)先申請(qǐng)內(nèi)存,提升申請(qǐng)內(nèi)存速度,減少內(nèi)存碎片。
  • 連接池(Connection Pooling):預(yù)先申請(qǐng)數(shù)據(jù)庫(kù)連接,提升申請(qǐng)連接的速度,降低系統(tǒng)的開(kāi)銷(xiāo)。
  • 實(shí)例池(Object Pooling):循環(huán)使用對(duì)象,減少資源在初始化和釋放時(shí)的昂貴損耗。

線程池的優(yōu)勢(shì)主要體現(xiàn)在以下 4 點(diǎn):

  • 降低資源消耗:通過(guò)池化技術(shù)重復(fù)利用已創(chuàng)建的線程,降低線程創(chuàng)建和銷(xiāo)毀造成的損耗。
  • 提高響應(yīng)速度:任務(wù)到達(dá)時(shí),無(wú)需等待線程創(chuàng)建即可立即執(zhí)行。
  • 提高線程的可管理性:線程是稀缺資源,如果無(wú)限制創(chuàng)建,不僅會(huì)消耗系統(tǒng)資源,還會(huì)因?yàn)榫€程的不合理分布導(dǎo)致資源調(diào)度失衡,降低系統(tǒng)的穩(wěn)定性。使用線程池可以進(jìn)行統(tǒng)一的分配、調(diào)優(yōu)和監(jiān)控。
  • 提供更多更強(qiáng)大的功能:線程池具備可拓展性,允許開(kāi)發(fā)人員向其中增加更多的功能。比如延時(shí)定時(shí)線程池ScheduledThreadPoolExecutor,就允許任務(wù)延期執(zhí)行或定期執(zhí)行。

同時(shí)阿里巴巴在其《Java開(kāi)發(fā)手冊(cè)》中也強(qiáng)制規(guī)定:線程資源必須通過(guò)線程池提供,不允許在應(yīng)用中自行顯式創(chuàng)建線程。

說(shuō)明:線程池的好處是減少在創(chuàng)建和銷(xiāo)毀線程上所消耗的時(shí)間以及系統(tǒng)資源的開(kāi)銷(xiāo),解決資源不足的問(wèn)題。如果不使用線程池,有可能造成系統(tǒng)創(chuàng)建大量同類(lèi)線程而導(dǎo)致消耗完內(nèi)存或者“過(guò)度切換”的問(wèn)題。

知道了什么是線程池以及為什要用線程池之后,我們?cè)賮?lái)看怎么用線程池。

線程池使用

線程池的創(chuàng)建方法總共有 7 種,但總體來(lái)說(shuō)可分為 2 類(lèi):

  • 一類(lèi)是通過(guò) ThreadPoolExecutor 創(chuàng)建的線程池;
  • 另一個(gè)類(lèi)是通過(guò) Executors 創(chuàng)建的線程池。

線程池的創(chuàng)建方式總共包含以下 7 種(其中 6 種是通過(guò) Executors 創(chuàng)建的,1 種是通過(guò)ThreadPoolExecutor 創(chuàng)建的):

  • Executors.newFixedThreadPool:創(chuàng)建一個(gè)固定大小的線程池,可控制并發(fā)的線程數(shù),超出的線程會(huì)在隊(duì)列中等待;
  • Executors.newCachedThreadPool:創(chuàng)建一個(gè)可緩存的線程池,若線程數(shù)超過(guò)處理所需,緩存一段時(shí)間后會(huì)回收,若線程數(shù)不夠,則新建線程;
  • Executors.newSingleThreadExecutor:創(chuàng)建單個(gè)線程數(shù)的線程池,它可以保證先進(jìn)先出的執(zhí)行順序;
  • Executors.newScheduledThreadPool:創(chuàng)建一個(gè)可以執(zhí)行延遲任務(wù)的線程池;
  • Executors.newSingleThreadScheduledExecutor:創(chuàng)建一個(gè)單線程的可以執(zhí)行延遲任務(wù)的線程池;
  • Executors.newWorkStealingPool:創(chuàng)建一個(gè)搶占式執(zhí)行的線程池(任務(wù)執(zhí)行順序不確定)【JDK 1.8 添加】。
  • ThreadPoolExecutor:最原始的創(chuàng)建線程池的方式,它包含了 7 個(gè)參數(shù)可供設(shè)置,后面會(huì)詳細(xì)講。

單線程池的意義從以上代碼可以看出 newSingleThreadExecutor 和 newSingleThreadScheduledExecutor 創(chuàng)建的都是單線程池,那么單線程池的意義是什么呢?答:雖然是單線程池,但提供了工作隊(duì)列,生命周期管理,工作線程維護(hù)等功能。

那接下來(lái)我們來(lái)看每種線程池創(chuàng)建的具體使用。

1.FixedThreadPool

創(chuàng)建一個(gè)固定大小的線程池,可控制并發(fā)的線程數(shù),超出的線程會(huì)在隊(duì)列中等待。

使用示例如下:

public static void fixedThreadPool() {
    // 創(chuàng)建 2 個(gè)數(shù)據(jù)級(jí)的線程池
    ExecutorService threadPool = Executors.newFixedThreadPool(2);

    // 創(chuàng)建任務(wù)
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            System.out.println("任務(wù)被執(zhí)行,線程:" + Thread.currentThread().getName());
        }
    };

    // 線程池執(zhí)行任務(wù)(一次添加 4 個(gè)任務(wù))
    // 執(zhí)行任務(wù)的方法有兩種:submit 和 execute
    threadPool.submit(runnable);  // 執(zhí)行方式 1:submit
    threadPool.execute(runnable); // 執(zhí)行方式 2:execute
    threadPool.execute(runnable);
    threadPool.execute(runnable);
}

執(zhí)行結(jié)果如下:

如果覺(jué)得以上方法比較繁瑣,還用更簡(jiǎn)單的使用方法,如下代碼所示:

public static void fixedThreadPool() {
    // 創(chuàng)建線程池
    ExecutorService threadPool = Executors.newFixedThreadPool(2);
    // 執(zhí)行任務(wù)
    threadPool.execute(() -> {
        System.out.println("任務(wù)被執(zhí)行,線程:" + Thread.currentThread().getName());
    });
}

2.CachedThreadPool

創(chuàng)建一個(gè)可緩存的線程池,若線程數(shù)超過(guò)處理所需,緩存一段時(shí)間后會(huì)回收,若線程數(shù)不夠,則新建線程。

使用示例如下:

public static void cachedThreadPool() {
    // 創(chuàng)建線程池
    ExecutorService threadPool = Executors.newCachedThreadPool();
    // 執(zhí)行任務(wù)
    for (int i = 0; i < 10; i++) {
        threadPool.execute(() -> {
            System.out.println("任務(wù)被執(zhí)行,線程:" + Thread.currentThread().getName());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
            }
        });
    }
}

執(zhí)行結(jié)果如下:

從上述結(jié)果可以看出,線程池創(chuàng)建了 10 個(gè)線程來(lái)執(zhí)行相應(yīng)的任務(wù)。

3.SingleThreadExecutor

創(chuàng)建單個(gè)線程數(shù)的線程池,它可以保證先進(jìn)先出的執(zhí)行順序。

使用示例如下:

public static void singleThreadExecutor() {
    // 創(chuàng)建線程池
    ExecutorService threadPool = Executors.newSingleThreadExecutor();
    // 執(zhí)行任務(wù)
    for (int i = 0; i < 10; i++) {
        final int index = i;
        threadPool.execute(() -> {
            System.out.println(index + ":任務(wù)被執(zhí)行");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
            }
        });
    }
}

執(zhí)行結(jié)果如下:

4.ScheduledThreadPool

創(chuàng)建一個(gè)可以執(zhí)行延遲任務(wù)的線程池。

使用示例如下:

public static void scheduledThreadPool() {
    // 創(chuàng)建線程池
    ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(5);
    // 添加定時(shí)執(zhí)行任務(wù)(1s 后執(zhí)行)
    System.out.println("添加任務(wù),時(shí)間:" + new Date());
    threadPool.schedule(() -> {
        System.out.println("任務(wù)被執(zhí)行,時(shí)間:" + new Date());
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
        }
    }, 1, TimeUnit.SECONDS);
}

執(zhí)行結(jié)果如下:

從上述結(jié)果可以看出,任務(wù)在 1 秒之后被執(zhí)行了,符合我們的預(yù)期。

5.SingleThreadScheduledExecutor

創(chuàng)建一個(gè)單線程的可以執(zhí)行延遲任務(wù)的線程池。

使用示例如下:

public static void SingleThreadScheduledExecutor() {
    // 創(chuàng)建線程池
    ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();
    // 添加定時(shí)執(zhí)行任務(wù)(2s 后執(zhí)行)
    System.out.println("添加任務(wù),時(shí)間:" + new Date());
    threadPool.schedule(() -> {
        System.out.println("任務(wù)被執(zhí)行,時(shí)間:" + new Date());
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
        }
    }, 2, TimeUnit.SECONDS);
}

執(zhí)行結(jié)果如下:

從上述結(jié)果可以看出,任務(wù)在 2 秒之后被執(zhí)行了,符合我們的預(yù)期。

6.newWorkStealingPool

創(chuàng)建一個(gè)搶占式執(zhí)行的線程池(任務(wù)執(zhí)行順序不確定),注意此方法只有在 JDK 1.8+ 版本中才能使用。

使用示例如下:

public static void workStealingPool() {
    // 創(chuàng)建線程池
    ExecutorService threadPool = Executors.newWorkStealingPool();
    // 執(zhí)行任務(wù)
    for (int i = 0; i < 10; i++) {
        final int index = i;
        threadPool.execute(() -> {
            System.out.println(index + " 被執(zhí)行,線程名:" + Thread.currentThread().getName());
        });
    }
    // 確保任務(wù)執(zhí)行完成
    while (!threadPool.isTerminated()) {
    }
}

執(zhí)行結(jié)果如下:

從上述結(jié)果可以看出,任務(wù)的執(zhí)行順序是不確定的,因?yàn)樗菗屨际綀?zhí)行的。

7.ThreadPoolExecutor

最原始的創(chuàng)建線程池的方式,它包含了 7 個(gè)參數(shù)可供設(shè)置。

使用示例如下:

public static void myThreadPoolExecutor() {
    // 創(chuàng)建線程池
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(5, 10, 100, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));
    // 執(zhí)行任務(wù)
    for (int i = 0; i < 10; i++) {
        final int index = i;
        threadPool.execute(() -> {
            System.out.println(index + " 被執(zhí)行,線程名:" + Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
}

執(zhí)行結(jié)果如下:

ThreadPoolExecutor 參數(shù)介紹

ThreadPoolExecutor 最多可以設(shè)置 7 個(gè)參數(shù),如下代碼所示:

 public ThreadPoolExecutor(int corePoolSize,
                           int maximumPoolSize,
                           long keepAliveTime,
                           TimeUnit unit,
                           BlockingQueue<Runnable> workQueue,
                           ThreadFactory threadFactory,
                           RejectedExecutionHandler handler) {
     // 省略...
 }

7 個(gè)參數(shù)代表的含義如下:

參數(shù) 1:corePoolSize

核心線程數(shù),線程池中始終存活的線程數(shù)。

參數(shù) 2:maximumPoolSize

最大線程數(shù),線程池中允許的最大線程數(shù),當(dāng)線程池的任務(wù)隊(duì)列滿了之后可以創(chuàng)建的最大線程數(shù)。

參數(shù) 3:keepAliveTime

最大線程數(shù)可以存活的時(shí)間,當(dāng)線程中沒(méi)有任務(wù)執(zhí)行時(shí),最大線程就會(huì)銷(xiāo)毀一部分,最終保持核心線程數(shù)量的線程。

參數(shù) 4:unit:

單位是和參數(shù) 3 存活時(shí)間配合使用的,合在一起用于設(shè)定線程的存活時(shí)間 ,參數(shù) keepAliveTime 的時(shí)間單位有以下 7 種可選:

  • TimeUnit.DAYS:天
  • TimeUnit.HOURS:小時(shí)
  • TimeUnit.MINUTES:分
  • TimeUnit.SECONDS:秒
  • TimeUnit.MILLISECONDS:毫秒
  • TimeUnit.MICROSECONDS:微妙
  • TimeUnit.NANOSECONDS:納秒

參數(shù) 5:workQueue

一個(gè)阻塞隊(duì)列,用來(lái)存儲(chǔ)線程池等待執(zhí)行的任務(wù),均為線程安全,它包含以下 7 種類(lèi)型:

  • ArrayBlockingQueue:一個(gè)由數(shù)組結(jié)構(gòu)組成的有界阻塞隊(duì)列。
  • LinkedBlockingQueue:一個(gè)由鏈表結(jié)構(gòu)組成的有界阻塞隊(duì)列。
  • SynchronousQueue:一個(gè)不存儲(chǔ)元素的阻塞隊(duì)列,即直接提交給線程不保持它們。
  • PriorityBlockingQueue:一個(gè)支持優(yōu)先級(jí)排序的無(wú)界阻塞隊(duì)列。
  • DelayQueue:一個(gè)使用優(yōu)先級(jí)隊(duì)列實(shí)現(xiàn)的無(wú)界阻塞隊(duì)列,只有在延遲期滿時(shí)才能從中提取元素。
  • LinkedTransferQueue:一個(gè)由鏈表結(jié)構(gòu)組成的無(wú)界阻塞隊(duì)列。與SynchronousQueue類(lèi)似,還含有非阻塞方法。
  • LinkedBlockingDeque:一個(gè)由鏈表結(jié)構(gòu)組成的雙向阻塞隊(duì)列。

較常用的是 LinkedBlockingQueue 和 Synchronous,線程池的排隊(duì)策略與 BlockingQueue 有關(guān)。

參數(shù) 6:threadFactory

線程工廠,主要用來(lái)創(chuàng)建線程,默認(rèn)為正常優(yōu)先級(jí)、非守護(hù)線程。

參數(shù) 7:handler

拒絕策略,拒絕處理任務(wù)時(shí)的策略,系統(tǒng)提供了 4 種可選:

  • AbortPolicy:拒絕并拋出異常。
  • CallerRunsPolicy:使用當(dāng)前調(diào)用的線程來(lái)執(zhí)行此任務(wù)。
  • DiscardOldestPolicy:拋棄隊(duì)列頭部(最舊)的一個(gè)任務(wù),并執(zhí)行當(dāng)前任務(wù)。
  • DiscardPolicy:忽略并拋棄當(dāng)前任務(wù)。

默認(rèn)策略為 AbortPolicy。

線程池的執(zhí)行流程

ThreadPoolExecutor 關(guān)鍵節(jié)點(diǎn)的執(zhí)行流程如下:

  • 當(dāng)線程數(shù)小于核心線程數(shù)時(shí),創(chuàng)建線程。
  • 當(dāng)線程數(shù)大于等于核心線程數(shù),且任務(wù)隊(duì)列未滿時(shí),將任務(wù)放入任務(wù)隊(duì)列。
  • 當(dāng)線程數(shù)大于等于核心線程數(shù),且任務(wù)隊(duì)列已滿:若線程數(shù)小于最大線程數(shù),創(chuàng)建線程;若線程數(shù)等于最大線程數(shù),拋出異常,拒絕任務(wù)。

線程池的執(zhí)行流程如下圖所示:

線程拒絕策略

我們來(lái)演示一下 ThreadPoolExecutor 的拒絕策略的觸發(fā),我們使用 DiscardPolicy 的拒絕策略,它會(huì)忽略并拋棄當(dāng)前任務(wù)的策略,實(shí)現(xiàn)代碼如下:

public static void main(String[] args) {
    // 任務(wù)的具體方法
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            System.out.println("當(dāng)前任務(wù)被執(zhí)行,執(zhí)行時(shí)間:" + new Date() +
                               " 執(zhí)行線程:" + Thread.currentThread().getName());
            try {
                // 等待 1s
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    // 創(chuàng)建線程,線程的任務(wù)隊(duì)列的長(zhǎng)度為 1
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1, 1,
                                                           100, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1),
                                                           new ThreadPoolExecutor.DiscardPolicy());
    // 添加并執(zhí)行 4 個(gè)任務(wù)
    threadPool.execute(runnable);
    threadPool.execute(runnable);
    threadPool.execute(runnable);
    threadPool.execute(runnable);
}

我們創(chuàng)建了一個(gè)核心線程數(shù)和最大線程數(shù)都為 1 的線程池,并且給線程池的任務(wù)隊(duì)列設(shè)置為 1,這樣當(dāng)我們有 2 個(gè)以上的任務(wù)時(shí)就會(huì)觸發(fā)拒絕策略,執(zhí)行的結(jié)果如下圖所示:

從上述結(jié)果可以看出只有兩個(gè)任務(wù)被正確執(zhí)行了,其他多余的任務(wù)就被舍棄并忽略了。其他拒絕策略的使用類(lèi)似,這里就不一一贅述了。

自定義拒絕策略

除了 Java 自身提供的 4 種拒絕策略之外,我們也可以自定義拒絕策略,示例代碼如下:

public static void main(String[] args) {
    // 任務(wù)的具體方法
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            System.out.println("當(dāng)前任務(wù)被執(zhí)行,執(zhí)行時(shí)間:" + new Date() +
                               " 執(zhí)行線程:" + Thread.currentThread().getName());
            try {
                // 等待 1s
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };
    // 創(chuàng)建線程,線程的任務(wù)隊(duì)列的長(zhǎng)度為 1
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(1, 1,
                                                           100, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1),
                                                           new RejectedExecutionHandler() {
                                                               @Override
                                                               public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                                                                   // 執(zhí)行自定義拒絕策略的相關(guān)操作
                                                                   System.out.println("我是自定義拒絕策略~");
                                                               }
                                                           });
    // 添加并執(zhí)行 4 個(gè)任務(wù)
    threadPool.execute(runnable);
    threadPool.execute(runnable);
    threadPool.execute(runnable);
    threadPool.execute(runnable);
}

程序的執(zhí)行結(jié)果如下:

究竟選用哪種線程池?

經(jīng)過(guò)以上的學(xué)習(xí)我們對(duì)整個(gè)線程池也有了一定的認(rèn)識(shí)了,那究竟該如何選擇線程池呢?

我們來(lái)看下阿里巴巴《Java開(kāi)發(fā)手冊(cè)》給我們的答案:

【強(qiáng)制】線程池不允許使用 Executors 去創(chuàng)建,而是通過(guò) ThreadPoolExecutor 的方式,這樣的處理方式讓寫(xiě)的同學(xué)更加明確線程池的運(yùn)行規(guī)則,規(guī)避資源耗盡的風(fēng)險(xiǎn)。
說(shuō)明:Executors 返回的線程池對(duì)象的弊端如下:
1) FixedThreadPool 和 SingleThreadPool:允許的請(qǐng)求隊(duì)列長(zhǎng)度為 Integer.MAX_VALUE,可能會(huì)堆積大量的請(qǐng)求,從而導(dǎo)致 OOM。
2)CachedThreadPool:允許的創(chuàng)建線程數(shù)量為 Integer.MAX_VALUE,可能會(huì)創(chuàng)建大量的線程,從而導(dǎo)致 OOM。

所以綜上情況所述,我們推薦使用 ThreadPoolExecutor 的方式進(jìn)行線程池的創(chuàng)建,因?yàn)檫@種創(chuàng)建方式更可控,并且更加明確了線程池的運(yùn)行規(guī)則,可以規(guī)避一些未知的風(fēng)險(xiǎn)。

到此這篇關(guān)于很多人竟然不知道Java線程池的創(chuàng)建方式有7種 的文章就介紹到這了,更多相關(guān)Java線程池創(chuàng)建內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java java.lang.InstantiationException異常案例詳解

    Java java.lang.InstantiationException異常案例詳解

    這篇文章主要介紹了Java java.lang.InstantiationException異常案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • spring boot 1.5.4 集成shiro+cas,實(shí)現(xiàn)單點(diǎn)登錄和權(quán)限控制

    spring boot 1.5.4 集成shiro+cas,實(shí)現(xiàn)單點(diǎn)登錄和權(quán)限控制

    這篇文章主要介紹了spring boot 1.5.4 集成shiro+cas,實(shí)現(xiàn)單點(diǎn)登錄和權(quán)限控制,需要的朋友可以參考下
    2017-06-06
  • 如何利用JConsole觀察分析Java程序的運(yùn)行并進(jìn)行排錯(cuò)調(diào)優(yōu)

    如何利用JConsole觀察分析Java程序的運(yùn)行并進(jìn)行排錯(cuò)調(diào)優(yōu)

    從Java 5開(kāi)始 引入了 JConsole。JConsole 是一個(gè)內(nèi)置 Java 性能分析器,可以從命令行或在 GUI shell 中運(yùn)行。您可以輕松地使用 JConsole(或者,它更高端的 “近親” VisualVM )來(lái)監(jiān)控 Java 應(yīng)用程序性能和跟蹤 Java 中的代碼
    2015-12-12
  • SpringBoot實(shí)現(xiàn)單文件上傳

    SpringBoot實(shí)現(xiàn)單文件上傳

    這篇文章主要為大家詳細(xì)介紹了SpringBoot實(shí)現(xiàn)單文件上傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 現(xiàn)代高效的java構(gòu)建工具gradle的快速入門(mén)

    現(xiàn)代高效的java構(gòu)建工具gradle的快速入門(mén)

    和Maven一樣,Gradle只是提供了構(gòu)建項(xiàng)目的一個(gè)框架,真正起作用的是Plugin,本文主要介紹了gradle入門(mén),文中通過(guò)示例代碼介紹的非常詳細(xì),感興趣的小伙伴們可以參考一下
    2021-11-11
  • mybatis 返回Integer,Double,String等類(lèi)型的數(shù)據(jù)操作

    mybatis 返回Integer,Double,String等類(lèi)型的數(shù)據(jù)操作

    這篇文章主要介紹了mybatis 返回Integer,Double,String等類(lèi)型的數(shù)據(jù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-11-11
  • SpringCloud Ribbon 負(fù)載均衡的實(shí)現(xiàn)

    SpringCloud Ribbon 負(fù)載均衡的實(shí)現(xiàn)

    Ribbon是一個(gè)客戶端負(fù)載均衡器,它提供了對(duì)HTTP和TCP客戶端的行為的大量控制。這篇文章主要介紹了SpringCloud Ribbon 負(fù)載均衡的實(shí)現(xiàn),感興趣的小伙伴們可以參考一下
    2019-01-01
  • SpringBoot綠葉顯示yml和端口問(wèn)題及解決方法

    SpringBoot綠葉顯示yml和端口問(wèn)題及解決方法

    今天是解決報(bào)錯(cuò)的一天,首先在操作Springboot中的時(shí)候,有些朋友的yml顯示的不是綠葉的圖標(biāo),或者是配置了之后不生效的問(wèn)題,今天就給大家分享SpringBoot綠葉顯示yml和端口問(wèn)題,感興趣的朋友一起看看吧
    2023-01-01
  • SpringBoot配置和切換Tomcat流程詳解

    SpringBoot配置和切換Tomcat流程詳解

    這篇文章主要介紹了如何給springboot配置和切換默認(rèn)的Tomcat容器以及相關(guān)的經(jīng)驗(yàn)技巧,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Java利用redis zset實(shí)現(xiàn)延時(shí)任務(wù)詳解

    Java利用redis zset實(shí)現(xiàn)延時(shí)任務(wù)詳解

    zset作為redis的有序集合數(shù)據(jù)結(jié)構(gòu)存在,排序的依據(jù)就是score。本文就將利用zset score這個(gè)排序的這個(gè)特性,來(lái)實(shí)現(xiàn)延時(shí)任務(wù),感興趣的可以了解一下
    2022-08-08

最新評(píng)論