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. eclipse的svn插件添加代理访问svn

    1.首先找到插件配置文件 C:\Users\Administrator\AppData\Roaming\Subversion这个目录下的servers文件 打开找到 # http-proxy-host ...

  2. P1382 楼房

    P1382 楼房 每个矩形拆成2个坐标按$x$轴排序,蓝后$multiset$维护最高值. #include<iostream> #include<cstring> #incl ...

  3. sqlloader parallel调用报ORA-26002: table has index defined upon it.解决方法

    ORA-26002: table has index defined upon it. This issue is caused when using the bulk load option in ...

  4. 利用shell脚本通过ssh绕过输入密码直接登录主机

    shell #!/usr/bin/expect spawn ssh root@192.168.137.141 expect "*password:" send "lizh ...

  5. Kali系列之multi/handler(渗透win7)

    环境 靶机 192.168.137.133 kali 192.168.137.135 步骤+ 生成后门 msfvenom -p windows/meterpreter/reverse_tcp LHOS ...

  6. 20145212罗天晨 WEB基础实践

    实验问题回答 1.什么是表单 表单在网页中主要负责数据采集功能 一个表单有三个基本组成部分: 表单标签 表单域:包含了文本框.密码框.隐藏域.多行文本框.复选框.单选框.下拉选择框和文件上传框等 表单 ...

  7. 20145325张梓靖 《网络对抗技术》 PC平台逆向破解

    20145325张梓靖 <网络对抗技术> PC平台逆向破解 学习任务 shellcode注入:shellcode实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对方的堆栈中,并 ...

  8. Minikube 安装

    安装Minikube 在容器编排工具中安装配置最复杂的就是Kubernetes,想要运行一个简单的容器集群环境,对于没有使用过Kubernetes的人来说,需要花费一定的时间去理解各组件的概念和功能, ...

  9. hihoCoder week17 最近公共祖先·三 lca st表

    记录dfs序列,dfn[tot] 记录第tot次访问的节点 然后查两点在dfs序中出现的第一次 id[u] id[v] 然后  找 dep[k] = min( dep[i] ) {i 属于 [id[u ...

  10. Kylin介绍2

    原理 官网 doc cube介绍 安装 案例 企业级特性 Apache Kylin 1.5的新功能和架构改变 Java  API 通过java代码对kylin进行cube build kylin从入门 ...