前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >java多线程开发容易犯的错误

java多线程开发容易犯的错误

作者头像
杉枫
发布于 2018-01-03 06:51:40
发布于 2018-01-03 06:51:40
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

      昨天在社区上看到有人讨论多线程使用,多线程遇到一些问题以及一些使用技巧记录一下。为什么要使用多线程,

不能是为了用而用,和设计模式一样用的合理,会让程序更易于理解,用的不合理反而会让程序变得更难理解。

      过去使用场景有,cms内容管理系统多个编辑配置频道,将多个频道以及频道下文章发布成静态html,如果单线程

我们一般是这么去做的,首先通过sql取得全部频道,对频道进行遍历,取到每个频道在取频道下文章列表,然后遍历

文章列表的每一片文章,对每一篇文章标题、作者、简介、内容、图片取出根据配置模版生成html文件,文章列表执

行完一个取下一个频道循环执行。直到所有频道发布完毕,这是整个站点发布完毕,发布过程结束。

      上述方式很好完成了发布这个需求,但是作为研发的我们有没有更好、更快方式去搞定这件事情呢?一定有的,

只要我们去想。如果我们将每个频道发布看成一个任务,通过多线程方式并行同时去发布频道那发布时间10个频道

理论上会成为原来10分之一,整个发布减少了时间、提升了性能,用户能够更快看到新内容、新文章。

      用多线程要对线程、线程池、同步机制不断学习,因为多线程是好东西,但坑也是很多。稍有不慎就会导致程序bug、

甚至死锁、线上cpu100%服务不可用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyVisiblility{
     private static boolean ready;
     private static int number;    
     private static class MyReaderThread extends Thread{
          public void run(){ //读线程
               while(!ready) 
                  Thread.yield();
               System.out.println(number);
          }
     public static void main(String [] args){ //主线程 
          new MyReaderThread().start();
          number=42;
          ready=true;
     }}

      这段程序有很大几率输出结果可能为0,也可能是死循环,跟我们期待不一样,原因是什么呢?线程对共享变量

的所有操作都必须在自己的工作内存中进行,不能直接从主线程中获取。因为副本主线程修改子线程为能收到。当

number变量不可见时输出结果为0,当ready不可见时子线程死循环。解决问题方式将变量加上volatile修饰词解决

多线程变量可见性问题。

即程序改为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyVisiblility{
     private static volatile boolean ready;
     private static volatile int number;    
     private static class MyReaderThread extends Thread{
          public void run(){ //读线程
               while(!ready) 
                  Thread.yield();
               System.out.println(number);
          }
     public static void main(String [] args){ //主线程 
          new MyReaderThread().start();
          number=42;
          ready=true;
     }}

个性化推荐系统(八)--- 机器学习深度学习召回集扩量这篇文章通过CountDownLatch实现主线程等待

多个计算线程同步,要将CountDownLatch.down()方法用在finally方法中,不要再其他地方,昨天review发现

线上再一个返回逻辑中用了CountDownLatch.down(),再finally中也用了,而finally中时一定会执行的,这时

相当于执行了两次主线程有几率不等待剩余线程向下执行,导致程序偶发bug,这个其实是对finally理解不到位。

再有就是经典HashMap用于多线程而没有用ConcurrentHashMap导致线上服务cpu100%详见这篇记一次双11大促压测线上服务cpu100%

再有就是ThreadLocal变量在ThreadPoolExecuter线程同时使用时,程序异常相见警惕ThreadLocal和ThreadPoolExecutor同时使用

      多线程使用好会提升程序性能简化程序实现,使用不好会引入bug、cpu100%、死循环、程序偶发不正确,并且

还不容易定位。这就要求我们要不断研究学习多线程技术,以保证优雅正确将多线程应用到线上服务以及其他各种场景。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-11-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
面试官:spring中定义bean的方法有哪些?我一口气说出了12种,把面试官整懵了。
在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜。我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工作中的多种业务场景。
苏三说技术
2021/07/08
6110
面试官:spring中定义bean的方法有哪些?我一口气说出了12种,把面试官整懵了。
17-SpringBoot自动配置-@Import详解
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到 IOC 容器中。
Devops海洋的渔夫
2022/03/23
2960
17-SpringBoot自动配置-@Import详解
实力总结四类Bean注入Spring的方式
一提到Spring,大家最先想到的是啥?是AOP和IOC的两大特性?是Spring中Bean的初始化流程?还是基于Spring的Spring Cloud全家桶呢?
阿Q说代码
2022/05/23
3560
实力总结四类Bean注入Spring的方式
Spring源码:bean的生命周期(一)
本节将正式介绍Spring源码细节,将讲解Bean生命周期。请注意,虽然我们不希望过于繁琐地理解Spring源码,但也不要认为Spring源码很简单。在本节中,我们将主要讲解Spring 5.3.10版本的源代码。如果您看到的代码与我讲解的不同,也没有关系,因为其中的原理和业务逻辑基本相同。为了更好地理解,我们将先讲解Bean的生命周期,再讲解Spring的启动原理和流程,因为启动是准备工作的一部分。
努力的小雨
2024/04/30
1580
Spring Framework 源码学习笔记(二)
测试运行时如何根据操作系统的不同来实例化不同的Bean?即如何选择性的注入Bean,这就需要用到@Conditional注解,定义选择条件需要实现Condition接口
RiemannHypothesis
2022/08/19
2670
Spring Framework 源码学习笔记(二)
SpringBoot基础(四):bean的多种加载方式
使用AnnotationConfigApplicationContext对象加载MyConfig,即使MyConfig类什么注解没有,也会被注册为bean。
Java微观世界
2025/01/21
1860
SpringBoot基础(四):bean的多种加载方式
【愚公系列】2023年10月 Java教学课程 166-SpringBoot自动配置(Enable注解原理和@Import详解)
SpringBoot中的@Enable注解是用来启用某些自动配置的功能,实际上@Enable注解是对@Import注解的封装,通过导入一个配置类来实现自动配置的功能。
愚公搬代码
2025/05/28
590
【Spring】Spring常用注解(上)
为了伟大的房产事业
2024/03/15
1220
扒一扒Bean注入到Spring的那些姿势
其实关于Bean注入Spring容器的方式网上也有很多相关文章,但是很多文章可能会存在以下常见的问题
捡田螺的小男孩
2023/02/22
4150
扒一扒Bean注入到Spring的那些姿势
逐行阅读Spring5.X源码(三) BeanDefinition的实现类详解,拔高
上回咱们讲了BeanDefinition的父接口及父接口实现类。本篇博文咱么继续讲BeanDefinition的实现类。包括AbstractBeanDefinition、RootBeanDefinition、ChildBeanDefinition、GenericBeanDefinition、AnnotateGenericBeanDefinition、ScannerGenericBeanDefinition。
源码之路
2020/09/04
1.8K0
逐行阅读Spring5.X源码(三) BeanDefinition的实现类详解,拔高
【小家Spring】Spring IoC容器中核心定义之------BeanDefinition深入分析(RootBeanDefinition、ChildBeanDefinition...)
在前面分析Spring IoC容器的时候,贯穿全文的一个概念:Bean定义信息。它是Spring容器的一个核心概念,那么本文就深入分析一下BeanDefinition这个接口(类)。
YourBatman
2019/09/03
7.5K1
【小家Spring】Spring IoC容器中核心定义之------BeanDefinition深入分析(RootBeanDefinition、ChildBeanDefinition...)
Spring 源码第四弹!深入理解 BeanDefinition
在 Spring 容器中,我们广泛使用的是一个一个的 Bean,BeanDefinition 从名字上就可以看出是关于 Bean 的定义。
江南一点雨
2020/07/07
4810
Spring 源码第四弹!深入理解 BeanDefinition
Spring学习笔记
1.Spring是一个开源框架,主要优势之一是其分层架构,分层架构允许使用者选择使用哪一个组件. Spring的核心是IOC(控制反转)和AOP(面向切面)。 2.IOC:创建类的对象的时候,使用ioc实现对象创建,通过配置文件方式创建对象。 底层原理技术:xml配置文件;dom4j解析xml文件;工厂模式;反射   AOP:不通过修改源代码方式增强类里面的方法。 3.spring框架需要的包:beans;core;context;SpEL;commons-logging-1.2; log4j-1.2.16; 4.配置文件:bean.xml   放到src下。   约束内容:
曼路
2018/10/18
3700
Spring学习笔记
深入探索Spring的Bean注入:四种方式解析与循环依赖探讨
本博客将深入探讨Spring中Bean的注入方式以及循环依赖的问题。我们将逐一介绍XML方式、注解方式(@Configuration + @Bean、@Import)、FactoryBean以及BeanDefinitionRegistryPostProcessor,通过实战演示向读者展示如何将Bean成功注入Spring容器。
猫头虎
2024/04/08
1.3K1
深入探索Spring的Bean注入:四种方式解析与循环依赖探讨
这些 Spring 面试加分项,必看!
最近在带大家做新项目,欢迎参与 大家好,我是鱼皮。 前言 我们一说到spring,可能第一个想到的是 IOC(控制反转) 和 AOP(面向切面编程)。 没错,它们是 spring 的基石,得益于它们的优秀设计,使得 spring 能够从众多优秀框架中脱颖而出。 除此之外,我们在使用 spring 的过程中,有没有发现它的扩展能力非常强。由于这个优势的存在,让 spring 拥有强大的包容能力,让很多第三方应用能够轻松投入 spring 的怀抱。比如:rocketmq、mybatis、redis等。 今天
程序员鱼皮
2023/03/29
2350
这些 Spring 面试加分项,必看!
被隔离了,聊一聊春(Spring)的生命周期
今天我们来分享一下Spring Bean的生命周期,Spring Bean的生命周期对于我们掌握Spring来说是很关键的,理解了Spring的生命周期,那么我们在开发的时候才能更好的利用Spring的功能,从而达到我们的目的!
小四的技术之旅
2022/07/26
3770
被隔离了,聊一聊春(Spring)的生命周期
Spring 学习笔记(2) Spring Bean
IoC 容器是 Spring 的核心,Spring 通过 IoC 容器来管理对象的实例化和初始化(这些对象就是 Spring Bean),以及对象从创建到销毁的整个生命周期。也就是管理对象和依赖,以及依赖的注入等等。
归思君
2023/10/16
2180
Spring 学习笔记(2) Spring Bean
springboot自动装配原理简书_万能轧机的装配原理
学习SpringBoot,绝对避不开自动装配这个概念,这也是SpringBoot的关键之一
全栈程序员站长
2022/09/23
5940
springboot自动装配原理简书_万能轧机的装配原理
SpringBoot中注册Bean的10种方式总结
在Spring Boot应用中,Bean是构成应用的核心组件。Spring容器负责管理这些Bean,包括它们的创建、配置、组装、管理和销毁。在Spring Boot中,有多种方式可以注册Bean,让Spring容器能够管理它们。本文将详细介绍这些不同的注册方式,并给出相应的示例代码和适用场景。
公众号:码到三十五
2024/08/11
1.5K0
【Spring注解驱动开发】在@Import中使用ImportBeanDefinitionRegistrar向容器中注册bean
作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
冰河
2020/10/29
4700
推荐阅读
相关推荐
面试官:spring中定义bean的方法有哪些?我一口气说出了12种,把面试官整懵了。
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验