iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Spring多线程的使用以及问题详解
  • 809
分享到

Spring多线程的使用以及问题详解

2024-04-02 19:04:59 809人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

目录前言为什么使用多线程SpringBoot中是否对多线程方法进行了封装如何控制线程运行中的各项参数corePoolSize:核心线程数maximumPoolSize:最大线程数ke

前言

由于本周大部分时间都在写原型,主要遇到的问题就是对实际功能理解不准确导致多次修改原型浪费了很多时间,这也就告诉我们一定要明确实际要求再去下手。

因为之前会议中也多次提到了线程,而我本人对线程没有什么理解于是便有了以下文章。

为什么使用多线程

在我们开发系统过程中,经常会处理一些费时间的任务(如:向数据库中插入大量数据),这个时候就就需要使用多线程。

springboot中是否对多线程方法进行了封装

是,Spring中可直接由@Async实现多线程操作

如何控制线程运行中的各项参数

通过配置线程池

线程池ThreadPoolExecutor执行规则如下

然后我们来认为构造一个线程池来试一下:

@Configuration
@EnableAsync
public class ThreadPoolConfig implements AsyncConfigurer {
  
  private static final int CORE_POOL_SIZE = 3;

  
  private static final int MAX_POOL_SIZE = 10;

  
  private static final int QUEUE_CAPACITY = 10;

  
  private static final int KEEP_ALIVE_SECONDS = 300;

  
  @Override
  @Bean
  public Executor getAsyncExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setMaxPoolSize(MAX_POOL_SIZE);
    executor.setCorePoolSize(CORE_POOL_SIZE);
    executor.setQueueCapacity(QUEUE_CAPACITY);
    executor.seTKEepAliveSeconds(KEEP_ALIVE_SECONDS);
    executor.setThreadNamePrefix("LiMingTest");
    // 线程池对拒绝任务(无线程可用)的处理策略
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    executor.initialize();
    return executor;
  }
}

ThreadPoolExecutor是jdk中的线程池实现,这个类实现了一个线程池需要的各个方法,它提供了任务提交、线程管理、监控等方法。

corePoolSize:核心线程数

线程池维护的最小线程数量,默认情况下核心线程创建后不会被回收(注意:设置allowCoreThreadTimeout=true后,空闲的核心线程超过存活时间也会被回收)。

大于核心线程数的线程,在空闲时间超过keepAliveTime后会被回收。

maximumPoolSize:最大线程数

线程池允许创建的最大线程数量。

当添加一个任务时,核心线程数已满,线程池还没达到最大线程数,并且没有空闲线程,工作队列已满的情况下,创建一个新线程,然后从工作队列的头部取出一个任务交由新线程来处理,而将刚提交的任务放入工作队列尾部。

keepAliveTime:空闲线程存活时间

当一个可被回收的线程的空闲时间大于keepAliveTime,就会被回收。

被回收的线程:

设置allowCoreThreadTimeout=true的核心线程。
大于核心线程数的线程(非核心线程)。

workQueue:工作队列

新任务被提交后,如果核心线程数已满则会先添加到工作队列,任务调度时再从队列中取出任务。工作队列实现了BlockingQueue接口。

handler:拒绝策略

当线程池线程数已满,并且工作队列达到限制,新提交的任务使用拒绝策略处理。可以自定义拒绝策略,拒绝策略需要实现RejectedExecutionHandler接口。

JDK默认的拒绝策略有四种:

AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
DiscardPolicy:丢弃任务,但是不抛出异常。可能导致无法发现系统的异常状态。
DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务。
CallerRunsPolicy:由调用线程处理该任务。

我们在非测试文件中直接使用new Thread创建新线程时编译器会发出警告:

不要显式创建线程,请使用线程池。
说明:使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者“过度切换”的问题

public class TestServiceImpl implements TestService {
  private final static Logger logger = LoggerFactory.getLogger(TestServiceImpl.class);
  @Override
  public void task(int i) {
      logger.info("任务: "+i);
  }
}
@Autowired
  TestService testService;
  @Test
  public void test() {
    for (int i = 0; i < 50; i++) {
      testService.task(i);
    }

我们可以看到一切执行正常;

之后我有对线程进行了一些测试:

class TestServiceImplTest {
  @Test
  public void test() {
    Thread add = new AddThread();
    Thread dec = new DecThread();
    add.start();
    dec.start();
    add.join();
    dec.join();
    System.out.println(Counter.count);
  }

  static class Counter {
    public static int count = 0;
  }

  class AddThread extends Thread {
    public void run() {
      for (int i=0; i<10000; i++) { Counter.count += 1; }
    }
  }

  class DecThread extends Thread {
    public void run() {
      for (int i=0; i<10000; i++) { Counter.count -= 1; }
    }
  }

一个自增线程,一个自减线程,对0进行同样次数的操作,理应结果仍然为零,但是执行结果却每次都不同。

经过搜索之后发现对变量进行读取和写入时,结果要正确,必须保证是原子操作。原子操作是指不能被中断的一个或一系列操作。

例如,对于语句: n +=1; 看似只有一行语句却包括了3条指令:

读取n, n+1, 存储n;

比如有以下两个进程同时对10进行加1操作

这说明多线程模型下,要保证逻辑正确,对共享变量进行读写时,必须保证一组指令以原子方式执行:即某一个线程执行时,其他线程必须等待。

static class Counter {
    public static final Object lock = new Object();//每个线程都需获得才能执行
    public static int count = 0;
  }

  class AddThread extends Thread {
    public void run() {
      for (int i=0; i<10000; i++) {
        synchronized(Counter.lock) { static class Counter {
    public static final Object lock = new Object();
    public static int count = 0;
  }

  class DecThread extends Thread {
    public void run() {
      for (int i=0; i<10000; i++) {
        synchronized(Counter.lock) {
          Counter.count -= 1;
        }
      }
    }
  }

值得注意的是每个类可以设置多个锁,如果线程获取的不是同一个锁则无法起到上述功能;

springBoot中也定义了很多类型的锁,在此就不一一说明了,我们目前能做到的就是注意项目中的异步操作,观察操作所使用的线程,做到在以后项目中遇到此类问题时能及时发现问题,解决问题。

总结

到此这篇关于Spring多线程的使用及问题的文章就介绍到这了,更多相关Spring多线程使用内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Spring多线程的使用以及问题详解

本文链接: https://www.lsjlt.com/news/149116.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Spring多线程的使用以及问题详解
    目录前言为什么使用多线程Springboot中是否对多线程方法进行了封装如何控制线程运行中的各项参数corePoolSize:核心线程数maximumPoolSize:最大线程数ke...
    99+
    2022-11-13
  • Java多线程之线程安全问题详解
    目录1. 什么是线程安全和线程不安全?2. 自增运算为什么不是线程安全的?3. 临界区资源和竞态条件总结:面试题: 什么是线程安全和线程不安全?自增运算是不是线程安全的?如何保证多线...
    99+
    2022-11-13
  • spring boot使用@Async注解解决异步多线程入库的问题
    目录前言项目实况介绍第一种方式第二种方式这里有个坑!这里有两个坑!总结前言 在开发过程中,我们会遇到很多使用线程池的业务场景,例如定时任务使用的就是ScheduledThreadPo...
    99+
    2022-11-13
  • C++中的多线程同步问题详解
    C++中的多线程同步问题详解在并发编程中,多线程同步是一个重要的问题。当多个线程同时访问共享资源时,会引发各种问题,如竞态条件(Race Condition)、死锁(Deadlock)和活锁(Livock),这些问题都会导致程序的不确定性和...
    99+
    2023-10-22
    C++ 多线程 同步问题
  • 详解C#异步多线程使用中的常见问题
    目录异常处理线程取消临时变量线程安全异常处理 小伙伴有没有想过,多线程的异常怎么处理,同步方法内的异常处理,想必都非常非常熟悉了。那多线程是什么样的呢,接着我讲解多线程的异常处理 首...
    99+
    2022-11-12
  • Linux之多线程以及多线程并发访问同一块内存的处理问题
    目录为什么需要多线程?多线程的优点最佳应用场景多线程的缺点验证思路总结为什么需要多线程? 并行实体共享同一个地址空间和所有可用数据 的这种能力是多进程锁无法表达的,因为多进程具有不同的地址空间;线程比进程更加轻量级,更加...
    99+
    2023-03-23
    Linux多线程 Linux多线程并发 多线程并发访问内存
  • Python多线程以及多线程中join()的使用方法
    本篇内容主要讲解“Python多线程以及多线程中join()的使用方法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python多线程以及多线程中join()的使用方法”吧!Python多线程与...
    99+
    2023-06-20
  • Spring 中的同步机制能否解决多线程问题?
    Spring是一个流行的Java开发框架,为Java开发者提供了许多便利的功能和工具。然而,当我们在使用Spring框架进行多线程编程时,我们是否需要考虑同步机制来解决多线程问题呢?这是一个值得讨论的问题。 首先,我们需要了解什么是同步机制...
    99+
    2023-09-21
    面试 同步 spring
  • 基于多线程并发的常见问题(详解)
    一 概述1.volatile保证共享数据一旦被修改就会立即同步到共享内存(堆或者方法区)中。2.线程访问堆中数据的过程线程在栈中建立一个数据的副本,修改完毕后将数据同步到堆中。3.指令重排为了提高执行效率,CPU会将没有依赖关系的指令重新排...
    99+
    2023-05-31
    多线程 并发 线程并发
  • Java多线程解决龟兔赛跑问题详解
    目录多线程4(龟兔赛跑-休眠线程)1.题目2.解题思路3.代码详解多线程4(龟兔赛跑-休眠线程) 1.题目 在龟兔赛跑中,领先的兔子因为通宵写博客,中途太累睡着了,跑输了乌龟。这个故...
    99+
    2022-11-13
  • Java使用线程同步解决线程安全问题详解
    第一种方法:同步代码块: 作用:把出现线程安全的核心代码上锁 原理:每次只能一个线程进入,执行完毕后自行解锁,其他线程才能进来执行 锁对象要求:理论上,锁对象只要对于当前同时执行的线...
    99+
    2022-11-13
  • Linux多线程及多线程并发访问同一块内存的问题怎么解决
    这篇文章主要介绍了Linux多线程及多线程并发访问同一块内存的问题怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Linux多线程及多线程并发访问同一块内存的问题怎么解决文章都会有所收获,下面我们一起来看...
    99+
    2023-07-05
  • Android多线程及异步处理问题详细探讨
    1、问题提出 1)为何需要多线程? 2)多线程如何实现? 3)多线程机制的核心是啥? 4)到底有多少种实现方式? 2、问题分析 1)究其为啥需要多线程的本质就是异步处理,直观一...
    99+
    2022-06-06
    android多线程 异步 线程 Android
  • Java多线程死锁问题详解(wait和notify)
    目录一. synchronnized 的特性1. 互斥性2. 可重入性二. 死锁问题1. 什么是死锁2. 死锁的四个必要条件3. 常见的死锁场景及解决3.1 不可重入造成的死锁3.2...
    99+
    2023-01-05
    Java多线程死锁 java死锁的原因及解决方法 java多线程死锁问题
  • 基于Spring Boot的线程池监控问题及解决方案
    目录前言为什么需要对线程池进行监控如何做线程池的监控数据采集数据存储以及大盘的展示进一步扩展以及思考如何合理配置线程池参数如何动态调整线程池参数如何给不同的服务之间做线程池的隔离实现...
    99+
    2022-11-13
  • C++中的多线程同步问题及解决方法
    C++中的多线程同步问题及解决方法多线程编程是提高程序性能和效率的一种方式,但同时也带来了一系列的同步问题。在多线程编程中,多个线程可能会同时访问和修改共享的数据资源,这可能导致数据的竞争条件、死锁、饥饿等问题。为了避免这些问题,我们需要使...
    99+
    2023-10-22
    多线程 (Multithreading) 同步 (synchronization) 解决方法 (Solution)
  • Python多线程以及多线程中join()的使用方法示例
    Python多线程与多进程中join()方法的效果是相同的。 下面仅以多线程为例: 首先需要明确几个概念: 知识点一: 当一个进程启动之后,会默认产生一个主线程,因为线程是程序执行流...
    99+
    2022-11-12
  • 关于多线程常用方法以及对锁的控制(详解)
    1.sleep() 使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是如果有Synchronized同步块,其他线程仍然不同访问共享数据。注意该方法要捕获异常比如有两个线程同时执行(没有S...
    99+
    2023-05-31
    多线程 控制
  • Springboot详解线程池与多线程及阻塞队列的应用详解
    目录一、案例场景二、使用类三、本例说明1.接收web请求2.后台任务处理3.关系说明四、代码1.OrderController2.FlowStarter流程启动器3.FlowMana...
    99+
    2022-11-13
  • 多线程编程中遇到的Python问题及解决方法
    多线程编程中遇到的Python问题及解决方法Python是一种广泛使用的编程语言,它有许多优点,其中之一就是可以通过多线程来提高程序的执行效率。然而,在多线程编程中,也会遇到一些常见的问题。本文将讨论一些常见的多线程编程问题,并提供相应的解...
    99+
    2023-10-22
    死锁(Deadlock):多线程编程中
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作