逐梦少年,看你能不能发现宝藏(11)


25.我们知道不安全,请编写一个不安全的案例并给出解决方案?
/** 集合类不安全的问题*ArrayList* */public class ContainerNotSafeDemo {public static void main(String[] args) {//new ArrayList();//构建一个空的arraylist,伴随着是一个空的长度为10的数组;//List list = Arrays.asList("a","b","c");//List list = Collections.synchronizedList(new ArrayList<>());List list = new CopyOnWriteArrayList<>();//List list = new ArrayList<>();list.forEach(System.out::println);for (int i = 1; i <= 30; i++) {new Thread(()->{list.add(UUID.randomUUID().toString().substring(0,8));System.out.println(list);},String.valueOf(i)).start();}//java.util.ConcurrentModificationException/** 1.故障现象*java.util.ConcurrentModificationException* 2.导致原因*并发争抢修改导致,参考我们的花名册签名情况 。*一个人则会那个在写入,另外一个同学过来争夺,导致数据不一致异常,并发修改异常,* 3.解决方案*1.new Vector<>();*2.List list = Collections.synchronizedList(new ArrayList<>());*3.new CopyOnWriteArrayList<>();* 4.优化建议(同样的错误不犯第2次)** *//** 笔记*写时复制* CopyOnWrite容器即写时复制的容器,往一个容器添加元素的时候,不直接往当前容器object[]添加,而是先将当前容器object[]进行Copy,复制出一个新的容器Object[]*newElement,然后新的容器object[] newElements里添加元素,添加完元素之后,再将复原容器的引用指向新的容器setArray(newElements);这样做的好处是可以对CopyOnWrite*容器进行并发的读,而不需要加锁,因为当前容器不会添加任何元素,所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器*public boolean add(E e) {final ReentrantLock lock = this.lock;lock.lock();try {Object[] elements = getArray();int len = elements.length;Object[] newElements = Arrays.copyOf(elements, len + 1);newElements[len] = e;setArray(newElements);return true;} finally {lock.unlock();}}* */}}
/** 集合类不安全的问题*HashSet也是一个不安全的集合,和ArrayList解决线程不安全的问题一样*hashset的底层是hashmap 。*那为什么hashset.set(6);可以直接添加一个呢?*因为它的add方法底层也是调用的hashmap的put方法,put的value是一个常量object,这个对象是null 。* */
也是不安全的,juc包里面有个可以解决并发问题 。
集合工具类里面也是有api对应的方法使得线程安全 。
26.公平锁/非公平锁/可重入锁/递归锁/自旋锁/ 谈谈你的理解?请手写一个自旋锁 。
? 1.公平锁:是指多个县城按照申请的顺序来获取锁,类似排队打饭,先来后到 。
? 2.非公平锁: 是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁,在高并发的情况下,有可能造成优先级反转 或饥饿现象 。
? 公平锁与非公平锁的区别:
? 公平锁/非公平锁,并发包中的创建可以指定构造函数的类型来得到公平锁或非公平锁,默认是非公平锁 。
? 关于两者的区别:
? **公平锁:a fair lock in the order in which theyit **
? 公平锁,就是很公平,在并发环境中,每个线程在获取锁时,会先查看此锁维护的等待队列,如果为空,或者当前线程时等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照Fifo的规则从队列中取到自己
? 非公平锁:非公平锁比较粗鲁,上来就直接尝试占有锁,如果尝试失败,就再采用类似公平锁的那种方式 。
? **java 而言,通过构造函数指定锁是否是公平锁,默认是非公平锁 。非公平锁的优点在于吞吐量比公平锁大 。**
? 对于而言,也是一种非公平锁 。
3.可重入锁(又名递归锁)
? 是指同一线程外层函数获得锁之后,内层递归函数仍然获取该锁的代码 。在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁 。