- 浏览: 2570251 次
- 性别:
- 来自: 广州
文章分类
- 全部博客 (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 1076public static void main(String[ ... -
解决tomcat中反序列化找不到class
2017-05-19 09:59 2089tomcat反序列化的过程中一直报ClassNotFoundE ... -
java的sun.jnu.encoding有什么用
2017-02-10 15:45 5383目前看到的影响有两个:影响类名的读取和Main方法参数的读取。 ... -
jsckson序列化处理泛型
2017-01-10 15:02 3264我有这样两个类 package com.vipshop. ... -
Quartz 1.8.0版本的死锁问题
2017-01-05 15:04 5653先说问题的结论:https:/ ... -
java的double乘法精度问题
2016-12-22 09:31 5521项目中实际的代码,我们实际的金额单位是元,精确到分,另外一个系 ... -
Calendar.getInstance()的坑
2016-12-06 16:50 5802Calendar.getInstance()看起来应该是个单例 ... -
针对jquery的when方法做的应变
2016-10-13 17:09 1067需求:a,b两个任务都处理(不管a,b是成功还是失败)后,执行 ... -
http的501错误
2016-10-09 15:37 8595普通的url请求是get put之类的,如果是乱七八糟的,比如 ... -
java对象初始化的顺序
2016-10-08 17:18 982public class Son extends F ... -
java线程池自己掉进去的坑
2016-08-18 17:59 2082java线程池的maximumPoolSize的生效条件真的是 ... -
java序列化框架性能比较
2016-05-24 09:22 32151. Kryo 2. FST 3. java 原生序列化 ... -
java 关闭main方法中的定时器线程(2)
2016-05-20 15:49 1772import java.util.concurrent ... -
java 关闭main方法中的定时器线程
2016-05-20 15:29 1171public class TestTreadClose { ... -
java比AtomicLong 更高效的LongAdder
2016-04-14 21:05 3183AtomicLong 是通过cas来实现的,已经很高效了,还有 ... -
java避免缓存伪共享
2016-04-14 20:15 903java8之前的做法: 加6个无用的long字段 如: ... -
java重复批次执行
2015-04-21 20:39 1464方案1 使用Phaser 方案2 使用CyclicBarr ... -
两个线程,分别打印[1,3,5]和[2,4,6],写一个程序,打印[1,2,3,4,5,6]。
2015-04-21 17:13 3895两个线程,分别打印[1,3,5]和[2,4,6],写一个程序, ... -
mina实现相同session后到的请求一定后处理的原理
2015-03-26 22:04 3704mina后面的业务处理是一个线程池去处理的,在线程池的多线程的 ... -
简单实现一个java公平策略的锁
2015-03-24 21:40 1365代码是: package com.eyu.gift.loc ...
相关推荐
线程死锁及解决办法.docx 线程锁之重入锁.docx 线程间的通信.docx 虚拟机内存结构和垃圾回收docx.docx 锁分类的了解.docx 集合的扩容机制.png SpringMVC部分.docx Spring部分.docx 第一题.pdf 第七题 谈谈MySQL支持...
多线程编程:线程的基本概念、线程同步、线程安全、死锁等问题。 JDBC:Java与数据库的交互,连接池的使用等。 Spring框架:Spring框架的基础概念、IOC容器、AOP等。 Hibernate框架:Hibernate框架的基础概念、ORM...
多线程put的时候可能导致元素丢失 68 解决方案 68 【集合】ConcurrentHashMap的get(),put(),又是如何实现的?ConcurrentHashMap有哪些问题?ConcurrentHashMap的锁是读锁还是写锁? 69 【集合】HashMap与HashTable...
数据结构与算法:最常见的各种排序,最好能手写 .. Java 高级:JVM 内存结构、垃圾回收器、回收算法...多线程状态图,状态如何流转? . 死锁,死锁原因 . 页锁、乐观锁、悲观锁? . 乐观锁如何保证线程安全? . 用过线
leetcode下载 Spring篇: spring为什么是单实例的?有什么好处? spring单实例如何解决有状态bean的线程安全问题的? ThreadLocal的原理? spring事务7种传播特性和隔离级别的理解?...多线程死锁如何排查(考察linux
面试题包括以下十九部分:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql...
springcloud-one 面试准备项目 一、基础面试问答 _谈谈HashMap_ HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干 ...
4. 解释一下JAVA中的多线程编程,包括线程的生命周期、同步和死锁等问题。 5. 解释一下JAVA中的集合框架,包括List、Set、Map等接口和实现类的使用。 6. 解释一下JAVA中的泛型编程,包括泛型类型参数、通配符等的...
三、多线程 13 35. 并行和并发有什么区别? 13 36. 线程和进程的区别? 14 37. 守护线程是什么? 14 38. 创建线程有哪几种方式? 14 39. 说一下 runnable 和 callable 有什么区别? 15 40. 线程有哪些状态? 15 41. ...
高级多线程控制类 ThreadLocal类1个每个线程本地只能保存一个变量副本,如果想要上线一个线程能够保存多个副本以上,就需要创建多个ThreadLocal。 2 ThreadLocal内部的ThreadLocalMap键为弱引用,会有内存泄漏的风险...
了解多线程所带来的安全风险.mp4 从线程的优先级看饥饿问题.mp4 从Java字节码的角度看线程安全性问题.mp4 synchronized保证线程安全的原理(理论层面).mp4 synchronized保证线程安全的原理(jvm层面).mp4 单例问题...
多线程 线程的创造 线程的生命周期 线程的同步 死锁 新特性 网络编程 网络通信协议 TCP协议与UDP协议 数据库 关系型数据库 MySQL SQL语句 DML,DCL,DDL 事物 索引 非关系型数据库 阶段二:JavaWEB XML格式 WEB...
第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个阶段并推荐学习并发的资料 ...
第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个阶段并推荐学习并发的资料 ...
第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个阶段并推荐学习并发的资料 ...
第2节理解多线程与并发的之间的联系与区别 [免费观看] 00:11:59分钟 | 第3节解析多线程与多进程的联系以及上下文切换所导致资源浪费问题 [免费观看] 00:13:03分钟 | 第4节学习并发的四个阶段并推荐学习并发的资料 ...
/ 3 文件系统接口 / 多道程序设计 / 主题介绍 / 4 线程实现HTML / PDF 用户和内核线程HTML / PDF 5 互斥HTML / PDF 生产者/消费者HTML / PDF 6 读者/作家HTML / PDF 餐饮哲学家HTML / PDF 7 死锁HTML / PDF 8 僵局/...
2018/09/15 周六 下午 15:47 28,460 Java多线程面试题50.docx 2018/10/03 周三 下午 17:15 22,866 Java用自定义的类作为HashMap的key值 实例详解.docx 2018/09/16 周日 上午 11:02 98,953 Java程序的执行过程.docx ...