classloader从1.6到1.7整体分成了两个版本。重点区别就是并行类加载。

  1.6版本

  protected synchronized Class loadClass(String name, boolean resolve)

  throws ClassNotFoundException

  {

  ……

  return c;

  }

  1.6版本加了一个方法锁。

  1.7版本

  private final ConcurrentHashMap parallelLockMap;

  protected Class loadClass(String name, boolean resolve)

  throws ClassNotFoundException

  {

  synchronized (getClassLoadingLock(name)) {

  ……

  return c;

  }

  }

  protected Object getClassLoadingLock(String className) {

  Object lock = this;

  if (parallelLockMap != null) {

  Object newLock = new Object();

  lock = parallelLockMap.putIfAbsent(className, newLock);

  if (lock == null) {

  lock = newLock;

  }

  }

  return lock;

  }

  1.7之后就是用了两种模式getClassLoadingLock方法中,我们可以看出有两种模式,一种是parallelLockMap为空,锁的对象是classloader本身,另外一种是parallelLockMap不为null。这里会根据classname去获取锁,如果有返回的object不为null。说明已经有class使用过了,如果为null,就把新建的object当做锁,达到了一个classname一个锁的效果。

  classloader加锁的原因

  有很多classloader的例子直接复写了loadClass但是没有加锁,只有读取文件加载的过程,这种classloader都是特定场合使用的。并不具备通用性。众所周知的一个规则,一个classloader不能加载相同类的字节码,第二次加载就会在defineclass的时候报错。

  场景1

  不同的线程可以是相同的classloader,两个线程的都是A classloader加载的,当里面的有个方法里都有B类时,两个线程都会触发A加载B类

  场景2

  双亲委托的情况,A loader是B loader的parent。A能加载到C类。B loader加载c的时候委托给A,A也在同时加载C。此时触发了两次A加载C。

  锁分离的好处

  锁分离加快了并发,这个是显而易见的。还有一个好处是减少了死锁。在编写javaagent的时候,只要在transform加点锁,特别容易和classloader还有类初始化时候的锁造成死锁。基本死锁的场景都在1.6。

  锁分离的案例

  jdk中锁分离的实现特别多

  读写分离

  双锁读写分离

  LinkedBlockingQueue有两把锁takeLock和putLock。

  由于队列的特性——FIFO。在写入的时候,竞争takeLock。读取的时候竞争putLock。以此达到同事读写的增加吞吐量的目的。

  副本机制读写分离

  副本机制读写分离的典型就是copyonwrite。

  CopyOnWriteArrayList。只有一把lock。但是使用的是数组存储。用volatile修饰。写入的时候获取锁,先用一个新的数组把旧的数据拷贝过来,然后把要加入的数据放入新数组中。最后替换 volatile的引用。读取的时候就直接获取volatile的数组。

  这样读取的时候只是那一刻的副本,一旦开始遍历,直到结束都不会有新的数据加入了。

  写写分离

  写写分离的场景是锁细化。classloader的改进算是写写分离的情况。典型的场景就是ConcurrentHashMap。ConcurrentHashMap的每个槽位一把锁,当没有hash冲突的时候,元素的写的过程是并行的。

  集群锁分离

  集群的锁分离的场景我们也用到的特别多。主要目的是提供并发。

  kafka 消费(读写分离)。kafka写log,达到一定限制就会开启新的文件,消费的时候,从旧的开始,就会从已经写好的开始读取。这种情况下,读文和写的文件是两个不同的文件。

  kafka topic分区。(写写分离)。kafka写入根据分区算法。分别写入不同的partition。类似的还有分库,分表。只要是水平扩展的基本都是写写分离的。

  主从机制(副本机制读写分离)。数据库使用主备方案,并且备份库只提供读取操作。至于新入的数据的空缺,一般由redis等缓存弥补。

从classloader的变更说起的更多相关文章

  1. 如何利用pt-online-schema-change进行MySQL表的主键变更

    业务运行一段时间,发现原来的主键设置并不合理,这个时候,想变更主键.这种需求在实际生产中还是蛮多的. 下面,看看pt-online-schema-change解决这类问题的处理方式. 首先,创建一张测 ...

  2. 使用自定义 classloader 的正确姿势

    详细的原理就不多说了,网上一大把, 但是, 看了很多很多, 即使看了jdk 源码, 说了罗里吧嗦, 还是不很明白: 到底如何正确自定义ClassLoader, 需要注意什么 ExtClassLoade ...

  3. Atitti 载入类的几种方法    Class.forName ClassLoader.loadClass  直接new

    Atitti 载入类的几种方法    Class.forName ClassLoader.loadClass  直接new 1.1. 载入类的几种方法    Class.forName ClassLo ...

  4. java笔记--理解java类加载器以及ClassLoader类

    类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...

  5. Class.forName和ClassLoader.loadClass等

    Class类 首先,Class类里可以记载所有类的属性.方法等信息.这个也就是运行时类别标记,它记录了所有的对象(比如int,MyClass,void,数组等等)对应的类信息. Class对象 JVM ...

  6. Map工具系列-07-TFS变更集提取工具

    所有cs端工具集成了一个工具面板 -打开(IE) Map工具系列-01-Map代码生成工具说明 Map工具系列-02-数据迁移工具使用说明 Map工具系列-03-代码生成BySQl工具使用说明 Map ...

  7. Java ClassLoader 原理详细分析(转)

    转载自:http://www.codeceo.com/article/java-classloader.html 一.什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管 ...

  8. [Tomcat] Tomcat的classloader

    定义 同其他服务器应用一样,tomcat安装了各种classloader(classes that implement java.lang.ClassLoader) Bootstrap | Syste ...

  9. win8 app GridView点击子项布局变更

    要触发点击必须设置IsItemClickEnabled="True" 要变更布局代码如下: private void gridView_ItemClick_1(object sen ...

随机推荐

  1. ltp makefile 解析

    困惑于 /include/mk/automake.mk中出现了第一个目标 而makefile却任然将all当做最终目标 测试了一番后发觉: ifeq ($(MAKE_3_80_COMPAT),1)# ...

  2. 使用sqlalchemy用orm方式写pipeline将scrapy item快速存入 MySQL

    传统的使用scrapy爬下来的数据存入mysql,用的是在pipeline里用pymysql存入数据库, 这种方法需要写sql语句,如果item字段数量非常多的 情况下,编写起来会造成很大的麻烦. 我 ...

  3. JDK源码之LinkedHashSet

    LinkedHashSet是HashSet和LinkList结合产生的集合,集合中的元素互不相同,且元素采用双向链表进行连接. 1.定义 LinkedHashSet继承了HashSet并且实现了Set ...

  4. Golang切片的三种简单使用方式及区别

    概念 切片(slice)是建立在数组之上的更方便,更灵活,更强大的数据结构.切片并不存储任何元素而只是对现有数组的引用. 三种方式及细节案例 ①定义一个切片,然后让切片去引用一个已经创建好的数组 pa ...

  5. 【python54--爬虫2】

    1.有道翻译 ''' |-- 代码思路解析: |-- 1.拿到网址首先查看network内Headers的:Request URL:User-Agent:From Data,这几个就是代码所需要的ur ...

  6. Click()与Submit()

    <input type="button" /> 定义可点击的按钮,但没有任何行为.如果你不写javascript 的话,按下去什么也不会发生. button 类型常用于 ...

  7. Linux命令2——b

    badblocks:检查磁盘设备中损坏的区块 -b:指定磁盘的区块大小,单位:字节 -c:一次检查几个区块 -i:由文件总读取已知的损坏区块,检查时会忽略这些区块 -o:检查的结果写入指定的输出文件. ...

  8. ZOJ 3632 ----dp+优先队列

    上个礼拜学长讲了优先队列的说.... emmmmmm.... 看着题解敲了一题...先m下. #include<cstring> #include<algorithm> #in ...

  9. mybatis配置文件resultMap标签的使用

    本文为博主原创,未经允许不得转载: resultMap标签是为了映射select查询出来结果的集合,其主要作用是将实体类中的字段与 数据库表中的字段进行关联映射. 注意:当实体类中的字段与数据库表中的 ...

  10. Latex: "Missing $ inserted" 解决方法

    参考: Latex报"Missing $ inserted"的解决方法 Latex: "Missing $ inserted" 解决方法 原因一:在文中出现&q ...