access数据库网站开发,网站相关前置许可,wordpress打赏积分功能,商贸有限公司起名字fail-safe 和fail-fast机制
Fail-fast#xff1a;快速失败
Fail-fast #xff1a; 表示快速失败#xff0c;在集合遍历过程中#xff0c;一旦发现容器中的数据被修改了#xff0c;会立刻抛出ConcurrentModificationException 异常#xff0c;从而导致遍历失败 package …
fail-safe 和fail-fast机制
Fail-fast快速失败
Fail-fast 表示快速失败在集合遍历过程中一旦发现容器中的数据被修改了会立刻抛出ConcurrentModificationException 异常从而导致遍历失败 package com.tianju.test;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class DemoTest {public static void main(String[] args) {ArrayListInteger list new ArrayList();list.add(1);list.add(2);IteratorInteger iterator list.iterator();while (iterator.hasNext()){Integer next iterator.next();list.add(55);System.out.println(next);}}
}Fail-safe失败安全
fail-safe表示失败安全也就是在这种机制下 出现集合元素的修改不会抛出 ConcurrentModificationException。
原因是采用安全失败机制的集合容器在遍历时不是直接在集合内容上访问的而是先 复制原有集合内容在拷贝的集合上进行遍历。由于迭代时是对原集合的拷贝进行遍历所以在遍历过程中对原集合所作的修改并不能被迭代器检测到。 package com.tianju.test;import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.CopyOnWriteArrayList;public class DemoTest2 {public static void main(String[] args) {CopyOnWriteArrayListInteger list new CopyOnWriteArrayList();list.add(1);list.add(2);IteratorInteger iterator list.iterator();while (iterator.hasNext()){Integer next iterator.next();list.add(55);System.out.println(next);}}
}
java.util.concurrent 包下的容器都是安全失败的,可以在多线程下并发使用,并发修改。
常见的的使用fail-safe 方式遍历的容器有ConcerrentHashMap 和 CopyOnWriteArrayList 等。
HashMap
hash冲突的问题
散列表Hash table 散列函数 哈希冲突 Hash 算法就是把任意长度的输入通过散列算法输出结果是散列值。
在hashMap中每个关键字被映射到从0到TableSize-1这个范围中的某个数并且被放到适当的单元中。这个映射就叫作散列函数(hash function),理想情况下它应该计算起来简单并且应该保证任何两个不同的关键字映射到不同的单元。不过这是不可能的因为单元的数目是有限的而关键字实际上是用不完的。因此我们寻找一个散列函数该函数要在单元之间均匀地分配关键字。 public final int hashCode() {return Objects.hashCode(key) ^ Objects.hashCode(value);}如何解决hash冲突 1开放定址法 也称为线性探测法就是从发生冲突的那个位置开始按照一定的次序从hash 表中找到一个空闲的位置然后把发生冲突的元素存入到这个空闲位置中。ThreadLocal 就用到了线性探测法来解决hash 冲突的。 2链式寻址法 这是一种非常常见的方法简单理解就是把存在hash 冲突的key 以单向链表的方式来存储比如HashMap 就是采用链式寻址法来实现的。 3再hash 法 就是当通过某个hash 函数计算的key 存在冲突时再用另外一个hash 函数对这个key 做hash一直运算直到不再产生冲突。这种方式会增加计算时间性能影响较大。 4建立公共溢出区: 就是把hash 表分为基本表和溢出表两个部分在冲突的元素一律放入到溢出表中。
HashMap链式寻址法红黑树解决hash 冲突
HashMap 在JDK1.8 版本中通过链式寻址法红黑树的方式来解决hash 冲突问题其中红黑树是为了优化Hash 表链表过长导致时间复杂度增加的问题。当链表长度大于8 并且hash 表的容量大于64 的时候再向链表中添加元素就会触发转化。 当链表长度大于8 并且hash 表的容量大于64 的时候再向链表中添加元素就会触发转化。 受检异常和非受检异常
Java基础8——java的异常机制初步 异常的捕获和处理 自定义异常
受检异常和非受检异常都是继承自Throwable 这个类中分别是Error 和Exception
Error 是程序报错系统收到无法处理的错误消息它和程序本身无关。Excetpion 是指程序运行时抛出需要处理的异常信息如果不主动捕获则会被jvm 处理。 受检异常的定义是程序在编译阶段必须要主动捕获的异常遇到该异常有两种处理方法 1通过try/catch 捕获该异常 2通过throw 把异常抛出去非受检异常的定义是程序不需要主动捕获该异常一般发生在程序运行期间比如 NullPointException 受检异常的定义是程序在编译阶段必须要主动捕获的异常遇到该异常有两种处理方法 为什么阿里巴巴的Java 开发手册不建议使用Java 自带的线程池
了解Java中线程池
Java进阶5——创建多线程的方法extends Thread和implements Runnable的对比 线程池及常用的线程池
4.【强制】线程池不允许使用Executors去创建而是通过ThreadPoolExecutor的方式这 样的处理方式让写的同学更加明确线程池的运行规则规避资源耗尽的风险。 Executors 里面默认提供的几个线程池是有一些弊端的如果是不懂多线程、或者是新手直接盲目使用就可能会造成比较严重的生产事故。
为什么不能用
1.FixedThreadPool 和SingleThreadPool 中阻塞队列长度是Integer.Max_Value一旦请求量增加就会堆积大量请求阻塞在队列中可能会造成内存溢出的问题 2.CachedThreadPool 和ScheduledThreadPool 中最大线程数量是Integer.Max_value一旦请求量增加导致创建大量的线程使得处理性能下降。 JDK 动态代理为什么只能代理有接口的类
在Java 里面动态代理是通过Proxy.newProxyInstance()方法来实现的它需要传入被动态代理的接口类。 加入如下代码进行运行
System.getProperties().put(sun.misc.ProxyGenerator.saveGeneratedFiles, true);或者加入下面这句
System.getProperties().put(jdk.proxy.ProxyGenerator.saveGeneratedFiles, true);JDK 动态代理会在程序运行期间动态生成一个代理类$Proxy0这个动态生成的代理类会继承java.lang.reflect.Proxy 类同时还会实现被代理类的接口。
在Java 中是不支持多重继承的而每个动态代理类都会继承Proxy 类(这也是JDK动态代理的实现规范) 所以就导致JDK 里面的动态代理只能代理接口而不能代理实现类。 spring中的代理
Spring进阶AOP的理解——静态/动态代理 面向切面编程AOPAspect Oriented Programming 日志记录 增强方法 如果一定要针对普通类来做动态代理可以选择cglib 这个组件它会动态生成一个被 代理类的子类子类重写了父类中所有非final 修饰的方法在子类中拦截父类的所有 方法调用从而实现动态代理。