线程不安全(Arraylist,HashSet,HashMap)和写时复制
package com.yangyuanyuan.juc1205; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet; /**
*
* 1 故障现象
* java.util.ConcurrentModificationException
*
* 2 导致原因
*
* 3 解决方法
* 3.1 new Vector<>()
* 3.2 Collections.synchronizedList(new ArrayList<>());
* 3.3 new CopyOnWriteArrayList()
*
*
* 4 优化建议(同样的错误不犯第2次) *
*/
public class NotSafeDemo03
{
public static void main(String[] args)
{
Map<String,String> map = new ConcurrentHashMap<>();
for (int i = 1; i <=30; i++)
{
new Thread(() -> {
map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,8));
System.out.println(map);
},String.valueOf(i)).start();
}
} public static void setNotSafe()
{
Set<String> set = new CopyOnWriteArraySet<>();
for (int i = 1; i <=30; i++)
{
new Thread(() -> {
set.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(set);
},String.valueOf(i)).start();
}
} public static void listNotSafe()
{
List<String> list = new CopyOnWriteArrayList();//Collections.synchronizedList(new ArrayList<>());//new Vector<>();//new ArrayList<>(); 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();
}
}
} /**笔记
* 写时复制
CopyOnWrite容器即写时复制的容器。往一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行Copy,
复制出一个新的容器Object[] newElements,然后新的容器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();
}
}
*/
线程不安全(Arraylist,HashSet,HashMap)和写时复制的更多相关文章
- JAVA中写时复制(Copy-On-Write)Map实现
1,什么是写时复制(Copy-On-Write)容器? 写时复制是指:在并发访问的情景下,当需要修改JAVA中Containers的元素时,不直接修改该容器,而是先复制一份副本,在副本上进行修改.修改 ...
- Java进阶知识点6:并发容器背后的设计理念 - 锁分段、写时复制和弱一致性
一.背景 容器是Java编程中使用频率很高的组件,但Java默认提供的基本容器(ArrayList,HashMap等)均不是线程安全的.当容器和多线程并发编程相遇时,程序员又该何去何从呢? 通常有两种 ...
- 写时复制集合 —— CopyOnWriteArrayList
前言 JUC 下面还有一个系列的类,都是 CopyOnWriteXXX ,意思是写时复制,这个究竟是怎么回事?那就以 CopyOnWriteArrayList 为切入点,一起了解写时复制是怎么回事? ...
- 写时复制和fork,vfork,clone
写时复制 原理: 用了“引用计数”,会有一个变量用于保存引用的数量.当第一个类构造时,string的构造函数会根据传入的参数从堆上分配内存,当有其它类需要这块内存时,这个计数为自动累加,当有类析构时, ...
- phpCOW机制(写时复制)
写时复制(Copy-on-Write,也缩写为COW),顾名思义,就是在写入时才真正复制一份内存进行修改. COW最早应用在*nix系统中对线程与内存使用的优化,后面广泛的被使用在各种编程语言中,如C ...
- php变量 写时改变 写时复制
写时复制 $var = 1; $var2 = $var; #此时$var2 与 $var 指向同一个zval refcount = 2: $var = 2; # 此时$val 改变 所以 $var 与 ...
- PHP写时复制, 变量复制和对象复制不同!!!
2016年3月18日 15:09:28 星期五 一直以为PHP对象也是写时复制....... 其实: PHP的变量是写时复制, 对象是引用的 写时复制: $a = $b; 如果$b的内容不改变, $a ...
- php 垃圾回收机制----写时复制和引用计数
PHP使用引用计数和写时复制来管理内存.写时复制保证了变量间复制值不浪费内存,引用计数保证了当变量不再需要时,将内存释放给操作系统. 要理解PHP内存管理,首先要理解一个概念----符号表. 符号表的 ...
- fork()和写时复制
写时复制技术最初产生于Unix系统,用于实现一种傻瓜式的进程创建:当发出fork( )系统调用时,内核原样复制父进程的整个地址空间并把复制的那一份分配给子进程.这种行为是非常耗时的,因为它需要: · ...
随机推荐
- Command3
压缩和解压 gzip gunzip .gz 指定文件必须带后缀 gzip file filename.gz zip unzip .zip unzip filename.zip directory zi ...
- LInux维护一:VirtualMachine磁盘扩容
- Go语言从入门到放弃(设置 go get 为国内源)
前言 Go语言学到 Gin 框架了, 其实每天学习是比较辛苦的事情, 坚持下去! 在使用 Go 过程中发现, 最无奈的是Go的一些模块下不下来, 即便挂了V, 油管2k不卡的那种, 依旧是 time ...
- python学习笔记 | wordcloud安装指南
问题: 直接在命令行输入: pip install wordcloud 不出意外,直接报错,显示缺失vc*****.bat,意思是缺失vc版本,这个安装方式基本可以扔掉. 解决: http://t.c ...
- Ubuntu_Gedit配置
Ubuntu_Gedit配置 为了换Ubuntu的时候能够更加方便,不用再用手重新打一遍代码,丢几个Gedit配置-- External Tools gdb compile (F2) #!/bin/s ...
- 解决Tengine健康检查引起的TIME_WAIT堆积问题
简介: 解决Tengine健康检查引起的TIME_WAIT堆积问题 一. 问题背景 "服务上云后,我们的TCP端口基本上都处于TIME_WAIT的状态"."这个问题在线下 ...
- 【Linux】rsync中sending incremental file list时间优化
每次使用rsync的时候,前面出现sending incremental file list 这句之后要等待很长时间 查了很多帖子和官方文档后,发现是-c这个选项的问题, -v, --verbose ...
- 【Oracle】userenv()函数介绍分析
说到这个userenv()使用起来还是很有用的 参数 功能 CLINET_INFO 返回最高可达64个字节存储的用户会话信 ...
- linux系统中set、env、export关系
set 用来显示shell变量(包括环境变量.用户变量和函数名及其定义),同时可以设置shell选项来开启调试.变量扩展.路径扩展等开关env 用来显示和设置环境变量export 用来显示和设置导出到 ...
- 记忆中的像素块褪色了吗?用开源的体素编辑器重新做个 3D 的吧!
本文适合对图形表现有兴趣的美术或者开发人员 本文作者:HelloGitHub-Joey 早期的的显示设备像素颗粒较大,使得显示内容的颗粒感严重,像是由一堆方块组成的.比较好的例子就是 GBA 上的游戏 ...