19.并发下的ArrayList、HashMap,Integer加锁问题
import java.util.ArrayList;
import java.util.Vector;
/**
* 并发下的ArrayList
*/
public class ArrayListMultiThread {
static ArrayList<Integer> arrayList = new ArrayList<>();
// static Vector<Integer> arrayList = new Vector<>(); //解决方式 使用线程安全的Vector代替ArrayList
public static class AddThread implements Runnable{
@Override
public void run() {
// synchronized (ArrayListMultiThread.class){ //解决方式加锁
for (int i = 0; i < 1000000; i++) {
arrayList.add(i);
}
// }
}
}
public static void main(String[] args) throws InterruptedException{
Thread thread1 = new Thread(new AddThread());
Thread thread2 = new Thread(new AddThread());
thread1.start();
thread2.start();
thread1.join();thread2.join();
System.out.println(arrayList.size());
//Exception in thread "Thread-1" java.lang.ArrayIndexOutOfBoundsException: 10
// at java.util.ArrayList.add(ArrayList.java:463)
// at com.combat.ArrayListMultiThread$AddThread.run(ArrayListMultiThread.java:11)
// at java.lang.Thread.run(Thread.java:748)
//1000001
//这种结果是因为ArrayList在扩容过程中,内部一致性被破坏,但由于没有锁的保护,另一个线程访问到了不一致的内部状态
//导致出现越界问题
//结果二:2000000
//结果二:小于2000000
}
}
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 并发下的HashMap
* jdk8
*/
public class HashMapMultiThread {
static Map<String,String> map = new HashMap<>();
// static ConcurrentHashMap<String,String> map = new ConcurrentHashMap<>(); //解决方式 用ConcurrentHashMap代替HashMap
public static class AddThread implements Runnable{
int start = 0;
public AddThread(int start){
this.start = start;
}
@Override
public void run() {
// synchronized (HashMapMultiThread.class){ // 解决方式
for (int i = start; i < 100000; i+=2) {
map.put(Integer.toString(i),Integer.toBinaryString(i));
}
// }
}
}
public static void main(String[] args) throws InterruptedException{
Thread thread1 = new Thread(new AddThread(0));
Thread thread2 = new Thread(new AddThread(1));
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(map.size());
//Exception in thread "Thread-1" Exception in thread "Thread-0" java.lang.ClassCastException: java.util.HashMap$Node cannot be cast to java.util.HashMap$TreeNode
// at java.util.HashMap$TreeNode.moveRootToFront(HashMap.java:1832)
// at java.util.HashMap$TreeNode.treeify(HashMap.java:1949)
// at java.util.HashMap.treeifyBin(HashMap.java:772)
// at java.util.HashMap.putVal(HashMap.java:644)
// at java.util.HashMap.put(HashMap.java:612)
// at com.combat.HashMapMultiThread$AddThread.run(HashMapMultiThread.java:19)
// at java.lang.Thread.run(Thread.java:748)
//java.lang.ClassCastException: java.util.HashMap$Node cannot be cast to java.util.HashMap$TreeNode
// at java.util.HashMap$TreeNode.moveRootToFront(HashMap.java:1832)
// at java.util.HashMap$TreeNode.putTreeVal(HashMap.java:2012)
// at java.util.HashMap.putVal(HashMap.java:638)
// at java.util.HashMap.put(HashMap.java:612)
// at com.combat.HashMapMultiThread$AddThread.run(HashMapMultiThread.java:19)
// at java.lang.Thread.run(Thread.java:748)
//2778
// 结果二:小于100000
//JDk7会出现死循环 HashMap put()是一个迭代遍历,如同遍历链表一样,但由于多线程,链表成环了,形成死循环
}
}
/**
* Integer加锁
*/
public class BadLockOnInteger implements Runnable{
public static Integer i = 0;
static BadLockOnInteger instance = new BadLockOnInteger();
@Override
public void run() {
for (int j = 0; j < 10000000; j++) {
synchronized (i){
// synchronized (instance){ // 修改方式
i++; //相当于 i = Integer.valueOf(i.intValue()+1);
}
}
}
public static void main(String[] args) throws InterruptedException{
Thread thread1 = new Thread(instance);
Thread thread2 = new Thread(instance);
thread1.start();thread2.start();
thread1.join();thread2.join();
System.out.println(i);
//12968375 小于20000000
//java中Integer属于不变对象,一旦创建就不可能被修改
//i++的本质是创建一个新的Integer对象,并将他的引用赋值给i
//两个线程每次加锁可能都加在了不同的对象实例上
}
}
19.并发下的ArrayList、HashMap,Integer加锁问题的更多相关文章
- Junit + String/Integer/ArrayList/HashMap/TreeMap 基本使用Demo
package JavaTest.test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; ...
- 2.8.3 并发下诡异的HashMap
package 第二章.并发下诡异的HashMap; import org.junit.Test; import java.util.HashMap;import java.util.Map;impo ...
- 2.8.2 并发下的ArrayList,以及源码分析
package 第二章.并发下的ArrayList; import java.util.ArrayList;import java.util.List; /** * Created by zzq on ...
- java 遍历方法 及 数组,ArrayList,HashMap,HashSet的遍历
一,遍历方法的实现原理 1.传统的for循环遍历,基于计数器的: 遍历者自己在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后,停止.主要就是需要按元素的位置来读取元素. ...
- HashMap<Integer, Bean> 根据Bean的属性进行排序
转载地址 已知一个HashMap<Integer,User>集合, User有name(String)和age(int)属性.请写一个方法实现对HashMap的排序功能,该方法接收Hash ...
- 性能优化:使用SparseArray代替HashMap<Integer,Object>(转)
HashMap是java里比较常用的一个集合类,我比较习惯用来缓存一些处理后的结果.最近在做一个Android项目,在代码中定义这样一个变量,实例化时,Eclipse却给出了一个 performanc ...
- Java基础知识强化之集合框架笔记55:Map集合之HashMap集合(HashMap<Integer,String>)的案例
1. HashMap集合(键是Integer,值是String的案例) 2. 代码示例: package cn.itcast_02; import java.util.HashMap; import ...
- 自己写的demo。List<HashMap<String,Object>>=new ArrayList<HashMap<String,Object>>
package com.pb.collection; import java.util.ArrayList; import java.util.HashMap; import java.util.It ...
- 将ArrayList<HashMap<String, String>>转为ArrayList<Bundle>类型的解决方案
Bundle是一种利用键值对存储的数据格式,而我们在程序中通常利用HashMap存储数据.在开发中,通过Http请求得到JSONArray类型的返回值,我选择利用ArrayList<HashMa ...
随机推荐
- RESTful (俗称:api接口文档)
整体规范建议采用RESTful 方式来实施. 协议 API与用户的通信协议,总是使用HTTPs协议,确保交互数据的传输安全. 域名 应该尽量将API部署在专用域名之下.https://api.exam ...
- C#基础提升系列——C# 泛型
C# 泛型(Generics) 泛型概述 泛型是C#编程语言的一部分,它与程序集中的IL(Intermediate Language,中间语言)代码紧密的集成.通过泛型,我们不必给不同的类型编写功能相 ...
- Linux Bash Shell快速入门 (三)
forfor 循环结构与 C 语言中有所不同,在 BASH 中 for 循环的基本结构是: for $var in dostatmentsdone 其中 $var 是循环控制变量, 是 $var 需要 ...
- CodeForces - 849B 几何
题意:给n个点,问是否能两条平行线覆盖所有的点 思路:因为要求全部覆盖,所以我们第一个点肯定是会入其中一条直线,其实只用判前三个点的所有情况即可 #include<stdio.h> #in ...
- nodejs 程序(有的功能和前端js是不一样的)
node文档:http://nodejs.cn/api/ 1.控制台输出 (node的输出是在命令框中输出的): 有颜色的输出 :console.log('\x1B[33m%s\x1b[0m:', p ...
- Apache + Tomcat 集群的配置
公司最近新接了一个项目,客户要求WEB SERVER 必须是APACHE,,由于之前的项目一直都是NGINX,,无奈啊,,由于对方的IT又是在三哥的过度,经过一番的争执只能顺应三哥三姐的要求..
- iOS开发环境搭建 及 编写1个hello world
参照: https://www.cnblogs.com/ansersion/p/9084460.html 前置条件 : MAC一台 安装xcode,从appstore 下载 xcode,(6G多,考验 ...
- js比较日期时间的大小
var myDate = new Date(); var timed = myDate.toLocaleDateString(); var oDate1 = new Date(item.express ...
- 哈希算法和字典类的定义,DataSet中数据遍历的几种方法
哈希算法的基本操作: 1. 哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似 ...
- static关键字_1
static关键字 1.在类中,用static声明的成员变量为静态成员变量,它为该类的公用变量,在第一次使用时被初始化,对于该类的所以对象来说,static成员变量只有一份. 2.用static声 ...