并发下的集合
Posted bockpecehhe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发下的集合相关的知识,希望对你有一定的参考价值。
ArrayList是一个线程不安全的容器 如下列程序
package com.longfor.dragonshard.service.cost.standard.impl; import java.util.ArrayList; public class ArrayListMultiThread { private static ArrayList arrayList = new ArrayList(); public static class AddThread implements Runnable{ @Override public void run() { for(int i=0;i<10000;i++){ arrayList.add(i); } } } public static void main(String[] args) throws InterruptedException{ Thread t1 = new Thread(new AddThread()); Thread t2 = new Thread(new AddThread()); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(arrayList.size()); } }
可能出现3中情况:
① 程序正常结束 所以说未必每次错误未必会表现出来
② 扩容过程中没有锁的保护 从而导致访问数据出错
③ 大小被不正常的访问 从而赋值出错
HashMap同样也是线程不安全的 问题比ArrayList更加诡异
package com.longfor.dragonshard.service.cost.standard.impl; import java.util.HashMap; import java.util.Map; public class HashMapMutiThread { private static Map map = new HashMap(); public static class AddThread implements Runnable{ public int start = 0; public AddThread(int start){ this.start=start; } @Override public void run() { for (int i=0;i<10000;i++){ map.put(Integer.toString(i),Integer.toBinaryString(i)); } } } public static void main(String[] args) throws InterruptedException{ Thread t1 = new Thread(new HashMapMutiThread.AddThread(0)); Thread t2 = new Thread(new HashMapMutiThread.AddThread(1)); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(map.size()); } }
错误的加锁
package com.longfor.dragonshard.service.cost.standard.impl; public class BadLockOnInteger implements Runnable{ public static Integer i = 0; public static BadLockOnInteger instance = new BadLockOnInteger(); @Override public void run() { for (int k=0;k<100000;k++){ synchronized (i){ i++; } } } public static void main(String[] args) throws InterruptedException{ Thread t1 = new Thread(instance); Thread t2 = new Thread(instance); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println(i); } }
Integer属于不变的对象 所以每次新增的时候都是新建一个新的Integer对象 重新赋值 i = Integer.valueOf(i.intValue()+1);
进一步查看valueOf
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
创建新的Integer对象 所以我们不能对Integer进行同步 因为Integer对象一直在改变
以上是关于并发下的集合的主要内容,如果未能解决你的问题,请参考以下文章