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加锁问题的更多相关文章

  1. Junit + String/Integer/ArrayList/HashMap/TreeMap 基本使用Demo

    package JavaTest.test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; ...

  2. 2.8.3 并发下诡异的HashMap

    package 第二章.并发下诡异的HashMap; import org.junit.Test; import java.util.HashMap;import java.util.Map;impo ...

  3. 2.8.2 并发下的ArrayList,以及源码分析

    package 第二章.并发下的ArrayList; import java.util.ArrayList;import java.util.List; /** * Created by zzq on ...

  4. java 遍历方法 及 数组,ArrayList,HashMap,HashSet的遍历

    一,遍历方法的实现原理 1.传统的for循环遍历,基于计数器的: 遍历者自己在集合外部维护一个计数器,然后依次读取每一个位置的元素,当读取到最后一个元素后,停止.主要就是需要按元素的位置来读取元素. ...

  5. HashMap<Integer, Bean> 根据Bean的属性进行排序

    转载地址 已知一个HashMap<Integer,User>集合, User有name(String)和age(int)属性.请写一个方法实现对HashMap的排序功能,该方法接收Hash ...

  6. 性能优化:使用SparseArray代替HashMap<Integer,Object>(转)

    HashMap是java里比较常用的一个集合类,我比较习惯用来缓存一些处理后的结果.最近在做一个Android项目,在代码中定义这样一个变量,实例化时,Eclipse却给出了一个 performanc ...

  7. Java基础知识强化之集合框架笔记55:Map集合之HashMap集合(HashMap<Integer,String>)的案例

    1. HashMap集合(键是Integer,值是String的案例) 2. 代码示例: package cn.itcast_02; import java.util.HashMap; import ...

  8. 自己写的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 ...

  9. 将ArrayList<HashMap<String, String>>转为ArrayList<Bundle>类型的解决方案

    Bundle是一种利用键值对存储的数据格式,而我们在程序中通常利用HashMap存储数据.在开发中,通过Http请求得到JSONArray类型的返回值,我选择利用ArrayList<HashMa ...

随机推荐

  1. 每天一个linux命令:tail(16)

    tail tail命令用于输入文件中的尾部内容,不指定文件时,作为输入信息进行处理.tail命令默认在屏幕上显示指定文件的末尾10行.命令从指定点开始将文件写到标准输出,使用tail命令的-f选项可以 ...

  2. git 往远端Dev推送

  3. mybatis的Date类型。

    在写select的时候,里面的查询语句.where后面如果jdbcType=DATE没有写的话是 这个形式的. <select id="selectPhoto" parame ...

  4. STM32输入捕获TIM2四通道

    相比于一通道,原子的例程里因为清了计数时间,所以要对程序进行修改. 记录上升沿后的计数,然后记录下降沿的计数.相减后计算高电平时间,对于定时器中断间隔的边界要分开处理. 这里因为我的接收机时间是1ms ...

  5. 【Dart学习】--之Iterable相关方法总结

    一,概述 按顺序访问的值或元素的集合, List集合也是继承于Iterable List和Set也是Iterable,dart:collection库中同样有很多 部分Iterable集合可以被修改 ...

  6. C# 简单软件有效期注册的实现

    ◆需求:公司一直以来对开发的产品都没有进行使用时间的控制,要么就是将日期限制写死在程序里面,每次都要编译新程序再发给客户,很不方便.于是公司让我写个模块,要求如下:1.无论哪个新开发的程序只要调用这个 ...

  7. 汉诺塔IX

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=76447#problem/E 汉诺塔IX Time Limit:1000MS     Me ...

  8. python生成接口自动化测试报告模版

    1:准备html模版 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &l ...

  9. ArcMap如何撤销配准

    ArcMap地理配准时,更新地理配准后,就没法撤销了. 如何解决呢,更新地理配准后,会在源文件夹中自动生成配准文件(文件格式为.over  .jgwx  .xml),可以通过删除这些文件来清除配准.

  10. js 使用技巧

    一,获取客户端状态 1.获取cookie function cookieInfo() { setcookie('cookie_test','1'); var cookie_test = getcook ...