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

spring boot中多線程開發(fā)的注意事項總結(jié)

 更新時間:2018年09月25日 08:57:51   作者:bigfan  
spring boot 通過任務(wù)執(zhí)行器 taskexecutor 來實現(xiàn)多線程和并發(fā)編程。下面這篇文章主要給大家介紹了關(guān)于spring boot中多線程開發(fā)的注意事項,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下

前言

Springt通過任務(wù)執(zhí)行器(TaskExecutor)來實現(xiàn)多線程和并發(fā)編程。使用ThreadPoolTaskExecutor可實現(xiàn)一個基于線程池的TaskExecutor。而實際開發(fā)中任務(wù)一般是非阻礙的,即異步的,所以我們要在配置類中通過@EnableAsync 開啟對異步任務(wù)的支持,并通過實際執(zhí)行Bean的方法中使用@Async注解來聲明其是一個異步任務(wù)。

基于springboot的多線程程序開發(fā)過程中,由于本身也需要注入spring容器進行管理,才能發(fā)揮springboot的優(yōu)勢。所以這篇文字主要用來記錄開發(fā)中兩者結(jié)合時需要注意的一些事項。

注意事項

第一步我們把線程類的實例注入sping容器進行管理

@Configuration
@SpringBootApplication
@Import({ThreadConfig.class})
public class ThreadApp implements CommandLineRunner
{
 public static void main(String[] args) throws Exception {

  ApplicationContext app = SpringApplication.run(ThreadApp .class, args);
  //這里主要保存上下文對象實例,需要加上。SpringBootUtils類網(wǎng)上很多,可以自己搜下
  SpringBootUtils.setApplicationContext(app);

 }

 //access command line arguments
 @Override
 public void run(String... args) throws Exception {
  //do something
 }
}

//ComponentScan注解會掃描com.demo.thead下,也就是多線程類所在的包下的文件
@Configuration
@ComponentScan(basePackages = { "com.demo.thread"})
public class ThreadConfig{

}

這里使用springboot @Import 注解,把ThreadConfig里掃描到的包中帶注解的示例,如@Component等注入到spring容器當中.

然后是線程的啟動,這里在我的業(yè)務(wù)場景中有兩種情況:

1、程序運行時,自動啟動;

這在一般的可執(zhí)行程序里面,當然可以直接在main函數(shù)里執(zhí)行通過代碼啟動線程。但在springboot中,我們可以使用@PostConstruct注解的方式,讓已經(jīng)注入bean容器的線程對象自啟動

@Component
public class demoThread extends Thread
{
 //注意這里,如果你沒有實現(xiàn)把多線程類的實例注入到spring容器中,這里你是無法拿到其他自動裝配的對象實例的的,這也是我們第一步的意義所在。
 @Autowired
 private XxxService xxxService;

 @PostConstruct
 public void start() {
  super.start();
 }

 public void run() {
  // Ok,在這里你就可以實現(xiàn)線程要實現(xiàn)的功能邏輯了,自然也可以直接使用裝配好的sevice對象實例。
  
 }
}

 2、在程序中,需要開啟線程時啟動,比如在從kafka接收數(shù)據(jù),開啟線程處理,當然這種情況下也需要通過第一步,把線程類實例注入到sping容器中

private TaskThread thread;
 private ExecutorService taskPool= new ThreadPoolExecutor(
   5, 10, 1000,
   TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10),
   new ThreadPoolExecutor.CallerRunsPolicy()); 


 @KafkaListener(topics = "xxTopic")
 public void receive(ConsumerRecord<Object, Object> consumerRecord) {
   JSONObject json = JSON.parseObject(consumerRecord.value().toString());
   //通過SpringBootUtils獲取線程類的實例
   thread = SpringBootUtils.getBean(TaskThread.class);
   //啟動線程
   //new Thread(thread).start() ; 
   //向線程對象里傳值
   thread.init(i);
   //放入線程池執(zhí)行
   taskPool.execute(thread);

 }
//注意這里是否添加@Scope("prototype")注解
@Component
@Scope("prototype")
public class TaskThread implements Runnable{
 
 protected int value=0;

 @Autowired
 private XxxService xxxService;
 
 //ThreadLocal 對象,單例模式下可以保證成員變量的線程安全和獨立性。
 public ThreadLocal<Integer> valueLocal = new ThreadLocal < Integer > () {
  @Override
  protected Integer initialValue() {
   return 0;
  }
 };

 protected static final Logger LOG = LoggerFactory.getLogger(GpsTaskThread.class);
 
 @Override
 public final void run() {
  try { 
   LOG.info(value+"");
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

 public void init(int Value) {
  this.value=Value;
 }
}

在這里我們需要注意,TaskThread這個線程類在spirngboot中是否要添加@Scope("prototype")注解設(shè)置為多例模式還是默認單例模式。

在單例模式下SpringBootUtils.getBean(TaskThread.class) 每次返回的都是同一個對象,雖然不需要每次都創(chuàng)建新的對象,但無法保證成員變量的線程安全,也就是說在線程池中的執(zhí)行的線程,它們的value值是共享的。而多例模式下,由于每次創(chuàng)建的都是一個新的線程對象,則不存在上述問題。

所以在這里請大家注意無論是我上面的示例代碼還是平常的web開發(fā)中,spirngboot默認為單例模式,自定義的成員變量是線程不安全的,需要通過ThreadLocal 或這其他方法做同步處理。

回到我們當前的業(yè)務(wù)場景,在這里我們需要每個線程處理的value值不同,互不影響,那么通過@Scope("prototype")注解把TaskThread設(shè)置為多例模式。

總結(jié)

通過上面的示例,我們可以看到springboot與多線程的結(jié)合還是比較簡單,通過配置,我們既可以在spring容器中管理線程類,也可以在線程中使用sping容器中的對象實例。同時我們在使用的過程當中要有意識的去注意線程安全方面的問題和內(nèi)部運行機制的問題。當然這里理解的還是比較淺顯,如果有不正確的地方還請大家指出與海涵。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • springboot獲取當前用戶信息的三種方式

    springboot獲取當前用戶信息的三種方式

    本文詳細介紹了在開發(fā)中獲取當前操作用戶信息的三種方式:使用ThreadLocal存儲用戶信息、通過攔截器和注解結(jié)合Shiro框架獲取用戶信息、以及使用Redis存儲用戶信息,每種方式都有具體的實現(xiàn)步驟和注意事項,可根據(jù)實際需求選擇合適的方法
    2024-10-10
  • SpringCloud如何解決服務(wù)之間的通信問題

    SpringCloud如何解決服務(wù)之間的通信問題

    本文主要介紹了SpringCloud如何解決服務(wù)之間的通信問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-08-08
  • SpringBoot多環(huán)境開發(fā)該如何配置

    SpringBoot多環(huán)境開發(fā)該如何配置

    這篇文章主要介紹了 SpringBoot多環(huán)境的開發(fā)配置詳情,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-09-09
  • java中基本數(shù)據(jù)類型與Object的關(guān)系說明

    java中基本數(shù)據(jù)類型與Object的關(guān)系說明

    這篇文章主要介紹了java基本數(shù)據(jù)類型與Object的關(guān)系說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java實現(xiàn)控制小數(shù)精度的方法

    Java實現(xiàn)控制小數(shù)精度的方法

    這篇文章主要介紹了Java實現(xiàn)控制小數(shù)精度的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • java實現(xiàn)簡單聊天軟件

    java實現(xiàn)簡單聊天軟件

    這篇文章主要為大家詳細介紹了java實現(xiàn)簡單的聊天軟件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 完美解決因數(shù)據(jù)庫一次查詢數(shù)據(jù)量過大導致的內(nèi)存溢出問題

    完美解決因數(shù)據(jù)庫一次查詢數(shù)據(jù)量過大導致的內(nèi)存溢出問題

    今天小編就為大家分享一篇完美解決因數(shù)據(jù)庫一次查詢數(shù)據(jù)量過大導致的內(nèi)存溢出問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • Spring boot集成RabbitMQ的示例代碼

    Spring boot集成RabbitMQ的示例代碼

    本篇文章主要介紹了Spring boot集成RabbitMQ的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • java使用正則表達式查找包含的字符串示例

    java使用正則表達式查找包含的字符串示例

    這篇文章主要介紹了java使用正則表達式查找包含的字符串功能,結(jié)合具體實例形式分析了java針對字符串匹配查找的相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2017-04-04
  • Java漢字轉(zhuǎn)拼音工具類完整代碼實例

    Java漢字轉(zhuǎn)拼音工具類完整代碼實例

    這篇文章主要介紹了java漢字轉(zhuǎn)拼音工具類完整代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03

最新評論