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

SpringBoot創(chuàng)建線程池的六種方式小結(jié)

 更新時間:2023年11月15日 15:40:31   作者:C3Stones  
本文主要介紹了SpringBoot創(chuàng)建線程池的六種方式小結(jié),包括自定義線程池,固定長度線程池,單一線程池,共享線程池,定時線程池,SpringBoot中注入異步線程池,感興趣的可以了解一下

1. 自定義線程池

1.1 示例代碼

/**
 * 自定義線程池
 * <p>
 * 優(yōu)點:可以自定義參數(shù)
 * </p>
 */
@Test
public void newThreadPoolExecutor() {
    ThreadPoolExecutor executor = new ThreadPoolExecutor(
            // 核心線程數(shù)
            3,
            // 最大線程數(shù)
            5,
            // 空閑線程最大存活時間
            60L,
            // 空閑線程最大存活時間單位
            TimeUnit.SECONDS,
            // 等待隊列及大小
            new ArrayBlockingQueue<>(100),
            // 創(chuàng)建新線程時使用的工廠
            Executors.defaultThreadFactory(),
            // 當線程池達到最大時的處理策略
//                new ThreadPoolExecutor.AbortPolicy()          // 拋出RejectedExecutionHandler異常
            new ThreadPoolExecutor.CallerRunsPolicy()       // 交由調(diào)用者的線程執(zhí)行
//                new ThreadPoolExecutor.DiscardOldestPolicy()  // 丟掉最早未處理的任務(wù)
//                new ThreadPoolExecutor.DiscardPolicy()        // 丟掉新提交的任務(wù)
    );

    // 總共5個任務(wù)
    for (int i = 1; i <= 5; i++) {
        int taskIndex = i;
        executor.execute(() -> {
            log.info("線程 " + Thread.currentThread().getName() + " 正在執(zhí)行任務(wù) " + taskIndex);

            // 每個任務(wù)耗時1秒
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

    executor.shutdown();
}

控制臺打?。?/p>

20:09:50.032 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-1 正在執(zhí)行任務(wù) 1
20:09:50.032 [pool-1-thread-2] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-2 正在執(zhí)行任務(wù) 2
20:09:50.032 [pool-1-thread-3] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-3 正在執(zhí)行任務(wù) 3
20:09:51.038 [pool-1-thread-2] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-2 正在執(zhí)行任務(wù) 5
20:09:51.038 [pool-1-thread-3] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-3 正在執(zhí)行任務(wù) 4

2. 固定長度線程池

2.1 示例代碼

/**
 * 固定大小線程池
 * <p>
 * 優(yōu)點:當任務(wù)執(zhí)行較快,且任務(wù)較少時使用方便
 * </p>
 * <p>
 * 風險:當處理較慢時,等待隊列的任務(wù)堆積會導致OOM
 * </p>
 */
@Test
public void newFixThreadPool() {
    // 3個固定線程
    ExecutorService executorService = Executors.newFixedThreadPool(3);

    // 總共5個任務(wù)
    for (int i = 1; i <= 5; i++) {
        int taskIndex = i;
        executorService.execute(() -> {
            log.info("線程 " + Thread.currentThread().getName() + " 正在執(zhí)行任務(wù) " + taskIndex);

            // 每個任務(wù)耗時1秒
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

    executorService.shutdown();
}

控制臺打?。?/p>

20:16:27.040 [pool-1-thread-2] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-2 正在執(zhí)行任務(wù) 2
20:16:27.040 [pool-1-thread-3] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-3 正在執(zhí)行任務(wù) 3
20:16:27.040 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-1 正在執(zhí)行任務(wù) 1
20:16:28.048 [pool-1-thread-3] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-3 正在執(zhí)行任務(wù) 4
20:16:28.048 [pool-1-thread-2] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-2 正在執(zhí)行任務(wù) 5

前3個任務(wù)被同時執(zhí)行,因為剛好有3個核心線程。后2個任務(wù)會被存放到阻塞隊列,當執(zhí)行前3個任務(wù)的某個線程空閑時會從隊列中獲取任務(wù)并執(zhí)行。

2.2 源碼剖析

/**
 * Creates a thread pool that reuses a fixed number of threads
 * operating off a shared unbounded queue.  At any point, at most
 * {@code nThreads} threads will be active processing tasks.
 * If additional tasks are submitted when all threads are active,
 * they will wait in the queue until a thread is available.
 * If any thread terminates due to a failure during execution
 * prior to shutdown, a new one will take its place if needed to
 * execute subsequent tasks.  The threads in the pool will exist
 * until it is explicitly {@link ExecutorService#shutdown shutdown}.
 *
 * @param nThreads the number of threads in the pool
 * @return the newly created thread pool
 * @throws IllegalArgumentException if {@code nThreads <= 0}
 */
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

該類型線程池的核心線程數(shù)和最大線程數(shù)為指定的參數(shù),空閑線程的存活線程時間為0毫秒,等待隊列使用LinkedBlockingQueue,初始化大小為Integer.MAX_VALUE(即:2147483647)。

當任務(wù)執(zhí)行較慢時,阻塞隊列存有大量的任務(wù)等待,這些任務(wù)會占用大量的內(nèi)存,從而可能導致OOM。

3. 單一線程池

3.1 示例代碼

/**
 * 單一線程池
 * <p>
 * 優(yōu)勢:保存任務(wù)按照提交的順序執(zhí)行
 * </p>
 * <p>
 * 風險:當處理較慢時,等待隊列的任務(wù)堆積會導致OOM
 * </p>
 */
@Test
public void newSingleThreadExecutor() {
    // 1個線程
    ExecutorService executor = Executors.newSingleThreadExecutor();

    // 總共5個任務(wù)
    for (int i = 1; i <= 5; i++) {
        int taskIndex = i;
        executor.execute(() -> {
            log.info("線程 " + Thread.currentThread().getName() + " 正在執(zhí)行任務(wù) " + taskIndex);

            // 每個任務(wù)耗時1秒
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

    executor.shutdown();
}

控制臺打印:

20:31:04.970 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-1 正在執(zhí)行任務(wù) 1
20:31:05.974 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-1 正在執(zhí)行任務(wù) 2
20:31:06.974 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-1 正在執(zhí)行任務(wù) 3
20:31:07.975 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-1 正在執(zhí)行任務(wù) 4
20:31:08.976 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-1 正在執(zhí)行任務(wù) 5

所有任務(wù)按照提交的順序執(zhí)行。

3.2 源碼剖析

/**
 * Creates an Executor that uses a single worker thread operating
 * off an unbounded queue. (Note however that if this single
 * thread terminates due to a failure during execution prior to
 * shutdown, a new one will take its place if needed to execute
 * subsequent tasks.)  Tasks are guaranteed to execute
 * sequentially, and no more than one task will be active at any
 * given time. Unlike the otherwise equivalent
 * {@code newFixedThreadPool(1)} the returned executor is
 * guaranteed not to be reconfigurable to use additional threads.
 *
 * @return the newly created single-threaded Executor
 */
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

該類型線程池的核心線程數(shù)和最大線程數(shù)都為1,空閑線程的存活線程時間為0毫秒,等待隊列使用LinkedBlockingQueue,初始化大小為Integer.MAX_VALUE(即:2147483647)。

當任務(wù)執(zhí)行較慢時,阻塞隊列存有大量的任務(wù)等待,這些任務(wù)會占用大量的內(nèi)存,從而可能導致OOM。

4. 共享線程池

4.1 示例代碼

/**
 * 共享線程池
 * <p>
 * 優(yōu)勢:當在某一時間段內(nèi)任務(wù)較多,且執(zhí)行較快時方便使用
 * </p>
 * <p>
 * 風險:當處理較慢時,會創(chuàng)建大量的線程
 * </p>
 */
@Test
public void newCachedThreadPool() {
    ExecutorService executor = Executors.newCachedThreadPool();

    // 總共5個任務(wù)
    for (int i = 1; i <= 5; i++) {
        int taskIndex = i;
        executor.execute(() -> {
            log.info("線程 " + Thread.currentThread().getName() + " 正在執(zhí)行任務(wù) " + taskIndex);

            // 每個任務(wù)耗時1秒
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }

    executor.shutdown();
}

控制臺打?。?/p>

20:45:31.351 [pool-1-thread-4] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-4 正在執(zhí)行任務(wù) 4
20:45:31.351 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-1 正在執(zhí)行任務(wù) 1
20:45:31.351 [pool-1-thread-5] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-5 正在執(zhí)行任務(wù) 5
20:45:31.358 [pool-1-thread-2] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-2 正在執(zhí)行任務(wù) 2
20:45:31.359 [pool-1-thread-3] INFO com.c3stones.test.ThreadPoolTest - 線程 pool-1-thread-3 正在執(zhí)行任務(wù) 3

每一個任務(wù)都創(chuàng)建了新的線程。

4.2 源碼剖析

/**
 * Creates a thread pool that creates new threads as needed, but
 * will reuse previously constructed threads when they are
 * available.  These pools will typically improve the performance
 * of programs that execute many short-lived asynchronous tasks.
 * Calls to {@code execute} will reuse previously constructed
 * threads if available. If no existing thread is available, a new
 * thread will be created and added to the pool. Threads that have
 * not been used for sixty seconds are terminated and removed from
 * the cache. Thus, a pool that remains idle for long enough will
 * not consume any resources. Note that pools with similar
 * properties but different details (for example, timeout parameters)
 * may be created using {@link ThreadPoolExecutor} constructors.
 *
 * @return the newly created thread pool
 */
public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

該類型線程池的核心線程數(shù)為0,最大線程數(shù)為Integer.MAX_VALUE(即:2147483647),空閑線程最大存活時間為60秒,等待隊列使用SynchronousQueue,該隊列不存儲數(shù)據(jù),只做轉(zhuǎn)發(fā),具體可參考:【并發(fā)編程】Java 阻塞隊列。

當任務(wù)較多或執(zhí)行較慢時,會創(chuàng)建大量的線程,從而導致OOM。

5. 定時線程池

5.1 示例代碼

/**
 * 定時線程池
 * <p>
 * 優(yōu)點:可以定時執(zhí)行某些任務(wù)
 * </p>
 * <p>
 * 風險:當處理較慢時,等待隊列的任務(wù)堆積會導致OOM
 * </p>
 */
@Test
public void newScheduledThreadPool() {
//        // 單一線程
//        ExecutorService executor = Executors.newSingleThreadScheduledExecutor();
    // 指定核心線程數(shù)
    ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);

    executor.schedule(() -> {
        log.info("3秒后開始執(zhí)行,以后不再執(zhí)行");

        // 每個任務(wù)耗時1秒
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }, 3, TimeUnit.SECONDS);
//
//        executor.scheduleAtFixedRate(() -> {
//            log.info("3秒后開始執(zhí)行,以后每2秒執(zhí)行一次");
//
//            // 每個任務(wù)耗時1秒
//            try {
//                TimeUnit.SECONDS.sleep(1);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }, 3, 2, TimeUnit.SECONDS);
//
//        executor.scheduleWithFixedDelay(() -> {
//            log.info("3秒后開始執(zhí)行,以后延遲2秒執(zhí)行一次");
//
//            // 每個任務(wù)耗時1秒
//            try {
//                TimeUnit.SECONDS.sleep(1);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//        }, 3, 2, TimeUnit.SECONDS);
}

控制臺打印 - 1:

21:18:46.494 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 3秒后開始執(zhí)行,以后不再執(zhí)行

啟動后3秒開始執(zhí)行,執(zhí)行完成后不再繼續(xù)執(zhí)行。

控制臺打印 - 2:

21:22:47.078 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 3秒后開始執(zhí)行,以后每2秒執(zhí)行一次
21:22:49.075 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 3秒后開始執(zhí)行,以后每2秒執(zhí)行一次
21:22:51.075 [pool-1-thread-2] INFO com.c3stones.test.ThreadPoolTest - 3秒后開始執(zhí)行,以后每2秒執(zhí)行一次

啟動后3秒開始執(zhí)行,以后每兩秒執(zhí)行一次。

控制臺打印 - 3:

21:28:09.701 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 3秒后開始執(zhí)行,以后延遲2秒執(zhí)行一次
21:28:12.705 [pool-1-thread-1] INFO com.c3stones.test.ThreadPoolTest - 3秒后開始執(zhí)行,以后延遲2秒執(zhí)行一次
21:28:15.707 [pool-1-thread-2] INFO com.c3stones.test.ThreadPoolTest - 3秒后開始執(zhí)行,以后延遲2秒執(zhí)行一次

啟動后3秒開始執(zhí)行,以后每次執(zhí)行時間為任務(wù)的耗時時間加固定的延遲時間。

假設(shè)每次任務(wù)固定延遲2秒,第一次任務(wù)在第3秒開始執(zhí)行,任務(wù)耗時1秒;第二次任務(wù)將在第一次完成后2秒開始執(zhí)行(即第6秒),耗時2秒;第三次任務(wù)將在第二次完成后2秒開始執(zhí)行(即第10秒),依次類推。

6. SpringBoot中注入異步線程池

6.1 自定義線程配置類

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

import java.util.concurrent.ThreadPoolExecutor;

/**
 * 自定義線程池配置類
 *
 * @author CL
 */
@Configuration
public class TaskExecutorConfig {

    /**
     * 自定義任務(wù)執(zhí)行器
     *
     * @return {@link TaskExecutor}
     */
    @Bean
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心線程數(shù),默認1
        int corePoolSize = Runtime.getRuntime().availableProcessors();
        executor.setCorePoolSize(corePoolSize);
        // 最大線程數(shù),默認Integer.MAX_VALUE
        executor.setMaxPoolSize(corePoolSize * 2 + 1);
        // 空閑線程最大存活時間,默認60秒
        executor.setKeepAliveSeconds(3);
        // 等待隊列及大小,默認Integer.MAX_VALUE
        executor.setQueueCapacity(500);
        // 線程的名稱前綴,默認該Bean名稱簡寫:org.springframework.util.ClassUtils.getShortName(java.lang.Class<?>)
        executor.setThreadNamePrefix("custom-thread-");
        // 當線程池達到最大時的處理策略,默認拋出RejectedExecutionHandler異常
//        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());         // 拋出RejectedExecutionHandler異常
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());    // 交由調(diào)用者的線程執(zhí)行
//        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy()); // 丟掉最早未處理的任務(wù)
//        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());       // 丟掉新提交的任務(wù)
        // 等待所有任務(wù)結(jié)束后再關(guān)閉線程池,默認false
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 等待所有任務(wù)結(jié)束最長等待時間,默認0毫秒
        executor.setAwaitTerminationSeconds(10);
        // 執(zhí)行初始化
        executor.initialize();
        return executor;
    }

}
  • 在Service注入使用
/**
 * 示例Service
 *
 * @author CL
 */
public interface DemoService {

    /**
     * 示例方法
     *
     * @return {@link String}
     */
    void demo();

}
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;


/**
 * 示例Service實現(xiàn)
 *
 * @author CL
 */
@Slf4j
@Service
public class DemoServiceImpl implements DemoService {

    @Resource
    private TaskExecutor taskExecutor;

    /**
     * 示例方法
     */
    @Override
    public void demo() {
        taskExecutor.execute(() -> {
            log.info("線程 " + Thread.currentThread().getName() + " 正在執(zhí)行Service中的方法");
        });
    }

}
  • 異步任務(wù)指定線程池
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;

/**
 * 示例異步任務(wù)
 *
 * @author CL
 */
@Slf4j
@Component
@EnableAsync
public class DemoAsync {

    /**
     * 示例方法
     */
    @Async(value = "taskExecutor")
    public void demo() {
        log.info("線程 " + Thread.currentThread().getName() + " 正在執(zhí)行Async中的方法");
    }

}
  • 定時任務(wù)調(diào)度指定線程池
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 自定義定時任務(wù)調(diào)度配置類
 *
 * @author CL
 */
@Configuration
public class SheduledConfig implements SchedulingConfigurer {

    /**
     * 配置定時任務(wù)
     *
     * @param scheduledTaskRegistrar 配置任務(wù)注冊器
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(taskScheduler());

//        // 第二種方式
//        scheduledTaskRegistrar.setScheduler(scheduledExecutorService());
    }

    /**
     * 自定義任務(wù)調(diào)度器
     *
     * @return {@link TaskScheduler}
     */
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler executor = new ThreadPoolTaskScheduler();
        executor.setPoolSize(5);
        executor.setThreadNamePrefix("custom-scheduler-");
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize();
        return executor;
    }

//    /**
//     * 自定義任務(wù)線程池
//     *
//     * @return {@link ScheduledExecutorService}
//     */
//    @Bean
//    public ScheduledExecutorService scheduledExecutorService() {
//        return Executors.newScheduledThreadPool(5);
//    }

}

6.2 測試

  • 編寫測試Controller
import com.c3tones.async.DemoAsync;
import com.c3tones.service.DemoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * 示例Controller
 *
 * @author CL
 */
@Slf4j
@RestController
public class DemoController {

    @Resource
    private DemoService demoService;

    @Resource
    private DemoAsync demoAsync;

    /**
     * Service示例方法
     *
     * @return {@link String}
     */
    @RequestMapping("/service")
    public void service() {
        log.info("Service示例方法開始執(zhí)行");
        demoService.demo();
        log.info("Service示例方法結(jié)束執(zhí)行");
    }

    /**
     * 異步示例方法
     *
     * @return {@link String}
     */
    @RequestMapping("/async")
    public void async() {
        log.info("異步示例方法開始執(zhí)行");
        demoAsync.demo();
        log.info("異步示例方法結(jié)束執(zhí)行");
    }

}
  • 啟動項目
  • 測試Service中的自定義線程池
curl http://127.0.0.1:8080/service

控制臺打印:

2023-03-19 22:26:26.896  INFO 136568 --- [nio-8080-exec-3] com.c3tones.controller.DemoController    : Service示例方法開始執(zhí)行
2023-03-19 22:26:26.897  INFO 136568 --- [nio-8080-exec-3] com.c3tones.controller.DemoController    : Service示例方法結(jié)束執(zhí)行
2023-03-19 22:26:26.897  INFO 136568 --- [custom-thread-1] com.c3tones.service.DemoServiceImpl      : 線程 custom-thread-1 正在執(zhí)行Service中的方法

調(diào)用接口同步打印日志,自定義線程異步執(zhí)行任務(wù)。

  • 測試異步任務(wù)中的自定義線程池
curl http://127.0.0.1:8080/async

控制臺打?。?/p>

2023-03-19 22:28:08.349  INFO 136568 --- [nio-8080-exec-7] com.c3tones.controller.DemoController    : 異步示例方法開始執(zhí)行
2023-03-19 22:28:08.355  INFO 136568 --- [nio-8080-exec-7] com.c3tones.controller.DemoController    : 異步示例方法結(jié)束執(zhí)行
2023-03-19 22:28:08.363  INFO 136568 --- [custom-thread-2] com.c3tones.async.DemoAsync              : 線程 custom-thread-2 正在執(zhí)行Async中的方法

調(diào)用接口同步打印日志,異步線程異步執(zhí)行任務(wù)。

測試定時任務(wù)中的自定義線程池

編寫測試方法

import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 示例定時任務(wù)
 *
 * @author CL
 */
@Slf4j
@Component
@EnableScheduling
public class DemoScheduled {

    /**
     * 示例方法
     */
    @Scheduled(cron = "0/3 * * * * ? ")
    public void demo() {
        log.info("線程 " + Thread.currentThread().getName() + " 正在執(zhí)行Scheduled中的方法");
    }

}

啟動服務(wù)

控制臺打?。?/p>

2023-03-19 22:30:24.002  INFO 136568 --- [tom-scheduler-3] com.c3tones.sheduled.DemoScheduled       : 線程 custom-scheduler-3 正在執(zhí)行Scheduled中的方法
2023-03-19 22:30:27.002  INFO 136568 --- [tom-scheduler-3] com.c3tones.sheduled.DemoScheduled       : 線程 custom-scheduler-3 正在執(zhí)行Scheduled中的方法
2023-03-19 22:30:30.001  INFO 136568 --- [tom-scheduler-3] com.c3tones.sheduled.DemoScheduled       : 線程 custom-scheduler-3 正在執(zhí)行Scheduled中的方法

定時任務(wù)從0秒開始,每3秒執(zhí)行一次任務(wù)。

7. 項目地址

thread-demo

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

相關(guān)文章

  • 解決scala.collection.mutable.Map寫入的問題

    解決scala.collection.mutable.Map寫入的問題

    這篇文章主要介紹了解決scala.collection.mutable.Map寫入的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Spring @Primary作用和實現(xiàn)原理詳解

    Spring @Primary作用和實現(xiàn)原理詳解

    今天分享一下Spring中的@Primary注解,Primary的意思是主要的,我們在使用spring的時候,難免會定義多個類型相同的bean,這時候如果不采取一些方法,那么是無法正常使用bean的,所以本就給大家介紹Spring @Primary的作用和實現(xiàn)原理
    2023-07-07
  • Java輕松實現(xiàn)批量插入或刪除Excel行列操作

    Java輕松實現(xiàn)批量插入或刪除Excel行列操作

    在職場生活中,對Excel工作表的行和列進行操作是非常普遍的需求,下面小編就來和大家介紹一下如何在Java中完成批量插入、刪除行和列的操作吧
    2023-10-10
  • Java農(nóng)夫過河問題的繼承與多態(tài)實現(xiàn)詳解

    Java農(nóng)夫過河問題的繼承與多態(tài)實現(xiàn)詳解

    這篇文章主要介紹了Java農(nóng)夫過河問題的繼承與多態(tài)實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • Security中的@PostAuthorize、@PreFilter和@PostFilter詳解

    Security中的@PostAuthorize、@PreFilter和@PostFilter詳解

    這篇文章主要介紹了Security中的@PostAuthorize、@PreFilter和@PostFilter詳解,@PostAuthorize是在方法調(diào)用完成后進行權(quán)限檢查,它不能控制方法是否能被調(diào)用,只能在方法調(diào)用完成后檢查權(quán)限決定是否要拋出AccessDeniedException,需要的朋友可以參考下
    2023-11-11
  • Spring Boot容器加載時執(zhí)行特定操作(推薦)

    Spring Boot容器加載時執(zhí)行特定操作(推薦)

    這篇文章主要介紹了Spring Boot容器加載時執(zhí)行特定操作及spring內(nèi)置的事件,需要的朋友可以參考下
    2018-01-01
  • java刪除指定目錄下所有空文件夾的方法

    java刪除指定目錄下所有空文件夾的方法

    這篇文章主要介紹了java刪除指定目錄下所有空文件夾的方法,涉及java針對文件與目錄的遍歷及目錄刪除相關(guān)操作技巧,需要的朋友可以參考下
    2016-08-08
  • Gradle修改本地倉庫的位置方法實現(xiàn)

    Gradle修改本地倉庫的位置方法實現(xiàn)

    這篇文章主要介紹了Gradle修改本地倉庫的位置方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07
  • 基于SpringBoot實現(xiàn)Web應(yīng)用的登錄與退出功能

    基于SpringBoot實現(xiàn)Web應(yīng)用的登錄與退出功能

    登錄與退出功能作為 Web 應(yīng)用中的基礎(chǔ)且重要的組成部分,直接關(guān)系到用戶的安全和隱私保護,所以本文給大家介紹了基于SpringBoot實現(xiàn)Web應(yīng)用的登錄與退出功能,文中有詳細的代碼供大家參考,需要的朋友可以參考下
    2024-04-04
  • java實現(xiàn)文本復制功能

    java實現(xiàn)文本復制功能

    這篇文章主要為大家詳細介紹了java實現(xiàn)文本復制功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11

最新評論