- 浏览: 2610893 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (880)
- 每日总结 (26)
- java (37)
- lucene 2.4源码学习 (11)
- 庖丁分词的源码分析 (5)
- cindy源码阅读 (10)
- jetty (3)
- java基础 (49)
- hadoop (37)
- python (7)
- 那些蛋疼的事 (15)
- 测试 (5)
- spring (3)
- redis (4)
- git (4)
- 我的开源项目 (2)
- linux (15)
- mysql (8)
- bootsharp (1)
- idea (1)
- Disruptor源码分析 (11)
- 高并发 (22)
- jdk (4)
- 领域驱动 (1)
- 坑 (6)
- 表达式框架 (7)
- 游戏 (3)
- Guava (1)
- 缓存 (1)
- 数据库 (1)
- 游戏项目 (3)
- java8 (1)
最新评论
-
hsluoyz:
PyCasbin是一个用Python语言打造的轻量级开源访问控 ...
权限管理的一个简单后台 -
liuyachao111:
谢谢 问题解决了
对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾 -
jnjeC:
多谢博主分享,在配置文件里的&也要改成& ...
对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾 -
大维啊:
同志,你这不行啊!
java 的 AccessController.doPrivileged使用 -
lisha2009:
解决了我的问题,多谢博主分享!
对实体 "characterEncoding" 的引用必须以 ';' 分隔符结尾
具体的死锁线程dump:
死锁发生的场景,我用多线程去createBean:
而启动的主线程恰好执行refresh。
产生的原因是:DefaultListableBeanFactory和DefaultSingletonBeanRegistry的好些方法都是锁的一个字段(就是一个map),这样一交叉,就出现死锁了。
我在想DefaultListableBeanFactory和DefaultSingletonBeanRegistry的那些方法都是说对象自己的话,不就不会死锁了吗。
spring为什么要锁这么小的粒度?这不是逼着人单线程去执行这些事情吗?
ps:我使用的版本是3.1.2,我在网上看到说这个是spring3.1.4之前的bug。。。。
我看了下spring3.2.4的代码确实有点不一样:在DefaultSingletonBeanRegistry修改了下防止出现死锁
ps:从这篇文章可以看到具体的死锁原因:
http://blog.csdn.net/u013536492/article/details/23935439
过程一: spring 容器初始化
Spring 容器初始化的时候会实例化所有单例对象( preInstantiateSingletons ),这个过程中会对上面两个对象加锁,以防止并发。先对 beanDefinitionMap 加锁,防止元数据被修改,然后在每次实例化单例对象的时候对 singletonObjects 加锁,防止并发修改。
过程二:根据 spring 容器获取一个单例对象。
调用 spring 容器的 context.getBean ( beanName ),如果该 bean 是单例且还未实例化,这个时候就需要进行实例化,如果该 bean 直接或间接存在注解方式的 bean 注入的时候,过程中也会对以上两个对象进行加锁防止并发。先对 singleObjects 加锁,从改 map 里找是否有存在 beanName 的对象,没有的话在创建该 bean 的过程中会对 beanDefinitionMap 加锁。
可以看出以上过程一和过程二对两个对象的锁顺序是不一致的,所以并发执行就可能会发生死锁。
我是觉得:最本质的原因是spring在get的时候发现没有,就会去创建一个,get的方法却做了set的事情,这个是原因所在。
Found one Java-level deadlock: ============================= "pool-3-thread-1": waiting to lock monitor 0x000000000aeaad68 (object 0x0000000780ffcf28, a java.util.concurrent.ConcurrentHashMap), which is held by "main" "main": waiting to lock monitor 0x000000000aeaaeb8 (object 0x0000000780ff4a30, a java.util.concurrent.ConcurrentHashMap), which is held by "pool-3-thread-1" Java stack information for the threads listed above: =================================================== "pool-3-thread-1": at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinitionNames(DefaultListableBeanFactory.java:297) - waiting to lock <0x0000000780ffcf28> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:329) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:320) at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:307) at org.springframework.context.support.AbstractApplicationContext.getBeanNamesForType(AbstractApplicationContext.java:1155) at com.my9yu.common.resource.reader.ReaderHolder.initialize(ReaderHolder.java:27) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:346) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:299) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:132) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:394) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1448) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225) - locked <0x0000000780ff4a30> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193) at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:876) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:818) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:735) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:286) at com.my9yu.common.resource.StorageManager.initializeStorage(StorageManager.java:118) at com.my9yu.common.resource.StorageManager.initialize(StorageManager.java:46) at com.my9yu.common.resource.StorageManagerFactory$StorageRunner.call(StorageManagerFactory.java:50) at com.my9yu.common.resource.StorageManagerFactory$StorageRunner.call(StorageManagerFactory.java:1) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) at java.util.concurrent.FutureTask.run(FutureTask.java:138) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) "main": at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:183) - waiting to lock <0x0000000780ff4a30> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:882) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:590) - locked <0x0000000780ffcf28> (a java.util.concurrent.ConcurrentHashMap) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:469) - locked <0x0000000780fd7bb0> (a java.lang.Object) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) at com.eyu.ahxy.Main.main(Main.java:21) Found 1 deadlock.
死锁发生的场景,我用多线程去createBean:
AutowireCapableBeanFactory beanFactory = this.applicationContext.getAutowireCapableBeanFactory(); Storage storage = beanFactory.createBean(Storage.class);
而启动的主线程恰好执行refresh。
产生的原因是:DefaultListableBeanFactory和DefaultSingletonBeanRegistry的好些方法都是锁的一个字段(就是一个map),这样一交叉,就出现死锁了。
我在想DefaultListableBeanFactory和DefaultSingletonBeanRegistry的那些方法都是说对象自己的话,不就不会死锁了吗。
spring为什么要锁这么小的粒度?这不是逼着人单线程去执行这些事情吗?
ps:我使用的版本是3.1.2,我在网上看到说这个是spring3.1.4之前的bug。。。。
我看了下spring3.2.4的代码确实有点不一样:在DefaultSingletonBeanRegistry修改了下防止出现死锁
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) {
ps:从这篇文章可以看到具体的死锁原因:
http://blog.csdn.net/u013536492/article/details/23935439
过程一: spring 容器初始化
Spring 容器初始化的时候会实例化所有单例对象( preInstantiateSingletons ),这个过程中会对上面两个对象加锁,以防止并发。先对 beanDefinitionMap 加锁,防止元数据被修改,然后在每次实例化单例对象的时候对 singletonObjects 加锁,防止并发修改。
过程二:根据 spring 容器获取一个单例对象。
调用 spring 容器的 context.getBean ( beanName ),如果该 bean 是单例且还未实例化,这个时候就需要进行实例化,如果该 bean 直接或间接存在注解方式的 bean 注入的时候,过程中也会对以上两个对象进行加锁防止并发。先对 singleObjects 加锁,从改 map 里找是否有存在 beanName 的对象,没有的话在创建该 bean 的过程中会对 beanDefinitionMap 加锁。
可以看出以上过程一和过程二对两个对象的锁顺序是不一致的,所以并发执行就可能会发生死锁。
我是觉得:最本质的原因是spring在get的时候发现没有,就会去创建一个,get的方法却做了set的事情,这个是原因所在。
发表评论
-
获取字符长度的正确姿势
2017-05-23 16:09 1130public static void main(String[ ... -
解决tomcat中反序列化找不到class
2017-05-19 09:59 2178tomcat反序列化的过程中一直报ClassNotFoundE ... -
java的sun.jnu.encoding有什么用
2017-02-10 15:45 5525目前看到的影响有两个:影响类名的读取和Main方法参数的读取。 ... -
jsckson序列化处理泛型
2017-01-10 15:02 3393我有这样两个类 package com.vipshop. ... -
Quartz 1.8.0版本的死锁问题
2017-01-05 15:04 5958先说问题的结论:https:/ ... -
java的double乘法精度问题
2016-12-22 09:31 5600项目中实际的代码,我们实际的金额单位是元,精确到分,另外一个系 ... -
Calendar.getInstance()的坑
2016-12-06 16:50 6001Calendar.getInstance()看起来应该是个单例 ... -
针对jquery的when方法做的应变
2016-10-13 17:09 1110需求:a,b两个任务都处理(不管a,b是成功还是失败)后,执行 ... -
http的501错误
2016-10-09 15:37 8736普通的url请求是get put之类的,如果是乱七八糟的,比如 ... -
java对象初始化的顺序
2016-10-08 17:18 1035public class Son extends F ... -
java线程池自己掉进去的坑
2016-08-18 17:59 2140java线程池的maximumPoolSize的生效条件真的是 ... -
java序列化框架性能比较
2016-05-24 09:22 32861. Kryo 2. FST 3. java 原生序列化 ... -
java 关闭main方法中的定时器线程(2)
2016-05-20 15:49 1818import java.util.concurrent ... -
java 关闭main方法中的定时器线程
2016-05-20 15:29 1231public class TestTreadClose { ... -
java比AtomicLong 更高效的LongAdder
2016-04-14 21:05 3229AtomicLong 是通过cas来实现的,已经很高效了,还有 ... -
java避免缓存伪共享
2016-04-14 20:15 953java8之前的做法: 加6个无用的long字段 如: ... -
java重复批次执行
2015-04-21 20:39 1500方案1 使用Phaser 方案2 使用CyclicBarr ... -
两个线程,分别打印[1,3,5]和[2,4,6],写一个程序,打印[1,2,3,4,5,6]。
2015-04-21 17:13 3969两个线程,分别打印[1,3,5]和[2,4,6],写一个程序, ... -
mina实现相同session后到的请求一定后处理的原理
2015-03-26 22:04 3752mina后面的业务处理是一个线程池去处理的,在线程池的多线程的 ... -
简单实现一个java公平策略的锁
2015-03-24 21:40 1415代码是: package com.eyu.gift.loc ...
相关推荐
TheadTool可能是自定义的工具类,用于简化多线程编程,比如提供线程的启动、停止、同步控制等功能。在Spring4中,我们可以利用`org.springframework.util.concurrent.ListenableFuture`或`java.util.concurrent....
线程中的操作往往涉及到多线程环境下的资源共享和管理,因此,如何在线程中正确地获取并使用Spring通过注解注入的对象,是一个常见的问题。本文将详细探讨这个主题。 首先,Spring的注解主要分为三类:配置注解(如...
多线程编程还需要关注死锁、活锁、饥饿等问题,以及如何有效地避免和解决这些问题。 在Spring框架中,多线程的应用主要体现在并发处理和异步任务上。Spring的`ThreadPoolTaskExecutor`和`AsyncConfigurer`接口可以...
4. **线程池管理**:Spring提供ThreadPoolTaskExecutor,我们可以自定义线程池配置,比如核心线程数、最大线程数、队列长度等,以优化多线程执行效率,并通过设置RejectedExecutionHandler处理拒绝策略。 5. **事务...
在IT行业中,多线程和Spring框架是两个非常重要的领域,尤其对于后端开发者来说,它们是必备的技术栈。下面将分别对这两个主题进行详细的知识点解析。 **多线程** 1. **线程概念**:线程是操作系统分配CPU时间片的...
多线程的设计可以提高消息处理的吞吐量,但需要注意线程安全问题,如锁的使用,以避免数据竞争和死锁。 8. **测试和调试**: 对于这样的多线程应用,进行充分的单元测试和集成测试是必要的,以确保在各种场景下都...
标题中的"spring boot多线程教学演示系统"表明这是一个基于Spring Boot框架的项目,用于教学和演示多线程技术的应用。Spring Boot是Java生态中一个流行的微服务开发框架,它简化了Spring应用的初始设置和配置,使得...
【标题】中的“多线程精品资源--novel”表明这是一个关于多线程编程的高质量学习资料,结合“基于时下最新 Java 技术栈 Spring Boot 3 + Vue 3 开发”,我们可以推断出这是一套综合了后端与前端开发的教程,主要聚焦...
在本课程中,"Spring Boot《Java课程》多线程教学演示系统(011733)",我们将深入探讨Java编程语言的核心特性之一——多线程,并结合Spring Boot框架构建一个实际的教学演示系统。这个系统将帮助我们理解如何在现代...
在本文中,我们主要探讨了在使用Spring Session以及Redis作为存储方式时,由于消息监听导致创建大量线程的问题及其解决方案。我们将从Spring Session的基础知识、Redis在Spring Session中的作用、监听机制导致线程...
通过这种方式,SpringMVC与多线程结合,可以优化复杂的Web应用程序,提升并发处理能力,为高并发场景提供更佳的性能表现。在实际项目中,还需要根据业务需求和系统资源进行合理的线程管理和优化。
- **死锁和竞态条件**:识别和预防这两种常见的多线程问题,确保程序的稳定性和可靠性。 - **线程通信**:了解`wait()`, `notify()`, `notifyAll()`方法以及`BlockingQueue`等同步机制,用于线程间的通信和协作。 - ...
在IT行业中,多线程并发编程是至关重要的一个领域,特别是在服务器端开发、大数据处理以及高性能计算中。这里提到的“多线程并发学习书籍”集合包含六本关于这一主题的专业书籍,覆盖了2012年至2018年的最新知识。...
Java多线程是Java编程中不可或缺的一个重要概念,它允许程序在同一时间执行多个任务,从而提高了计算机系统的资源利用率和程序的响应速度。本篇将详细阐述Java多线程的基础知识,包括线程的概念、创建线程的方式以及...
然而,多线程也带来了挑战,比如竞态条件、死锁、资源争抢等问题,这些都需要通过同步机制如`synchronized`关键字、Locks(如ReentrantLock)以及volatile变量来解决。另外,Java提供了ThreadLocal来解决线程局部...
理解线程同步机制,如synchronized、wait/notify、ReentrantLock等,以及死锁、活锁、饥饿等问题的预防和处理,都是深入学习多线程并发的重要内容。 2. **JVM(Java虚拟机)**:JVM是Java程序运行的平台,理解其...
同时,Spring框架提供的线程池功能则可以帮助我们优化多线程环境下的性能,特别是处理并发请求时。在这个主题中,我们将深入探讨如何利用Spring MVC与Spring线程池来有效地管理并发请求,并解决数据同步控制问题。 ...
本文将围绕"多线程学习代码"这个主题,详细讲解其中涉及的Spring动态代理和Java多线程锁的使用,并探讨与JVM特性相关的知识。 首先,让我们来关注Spring框架中的动态代理。动态代理主要分为两种类型:JDK动态代理和...
在Java编程领域,分布式多线程中间件是高级主题,涉及到复杂的系统设计和优化。本教程合集将深入探讨这些核心概念,旨在帮助开发者提升技能并应对大型、高并发的应用场景。 首先,让我们来理解“Java高级教程”的...
这份资源包含了Java基础、多线程、Spring框架、Spring Boot、MySQL数据库、Redis缓存以及消息队列MQ等多个核心知识点,每个部分都涵盖了经典且常见的面试问题。 1. **Java基础篇**: - 内存模型:了解JVM内存结构...