多线程并发修改集合案例
//单线程使用 修改集合
ArrayList arrayList = new ArrayList();
for (int i = 0; i < 100; i++) {
arrayList.add(i);
}
int batch = 10;
int size = arrayList.size();
if (0 < size && size <= batch) {
List list = arrayList.subList(0, size);
System.out.println(">>>>>>>>>>>>:" + JSON.toJSONString(list));
} else {
int flag = size % batch == 0 ? size / batch : size / batch + 1;
for (int i = 0; i < flag; i++) {
if (i == flag - 1) {
List list = arrayList.subList(0, arrayList.size());
System.out.println(">>>>>>>>>>>>:" + JSON.toJSONString(list));
arrayList.removeAll(list);
} else {
List list = arrayList.subList(0, batch);
System.out.println(">>>>>>>>>>>>:" + JSON.toJSONString(list));
arrayList.removeAll(list);
}
}
}
//多线程 步长【0,10,20,30,40】修获取 集合上的位置各索引的值
ArrayList arrayList = new ArrayList();
for (int i = 0; i < 10000; i++) {
arrayList.add(i);
}
int batch = 10;
int size = arrayList.size();
if (0 < size && size <= batch) {
List list = arrayList.subList(0, size);
threadPoolExecutor.submit(() -> {
print0(list);
});
} else {
int flag = size % batch == 0 ? size / batch : size / batch + 1;
for (int i = 0; i < flag; i++) {
List list;
if (i == flag - 1) {
list = arrayList.subList(i * batch, arrayList.size());
} else {
list = arrayList.subList(i * batch, (i + 1) * batch);
}
threadPoolExecutor.submit(() -> {
print0(list);
});
}
}
下面这个是错误案例:
//多线程并发修改
ArrayList arrayList = new ArrayList();
for (int i = 0; i < 100; i++) {
arrayList.add(i);
}
// ArrayList:
// System.arraycopy
// System.arraycopy(elementData, 0, a, 0, size);
// array.copy 【里面实现使用】浅复制 索引修改后对原数据造成影响
// CopyOnWriteArrayList
// es = Arrays.copyOf(es, es.length, Object[].class);
CopyOnWriteArrayList copyOnWriteArrayList = new CopyOnWriteArrayList(arrayList);
int batch = 10;
int size = copyOnWriteArrayList.size();
if (0 < size && size <= batch) {
List list = copyOnWriteArrayList.subList(0, size);
threadPoolExecutor.submit(() -> {
print0(list);
});
} else {
int flag = size % batch == 0 ? size / batch : size / batch + 1;
for (int i = 0; i < flag; i++) {
List list;
if (i == flag - 1) {
list = copyOnWriteArrayList.subList(0, copyOnWriteArrayList.size());
} else {
list = copyOnWriteArrayList.subList(0, batch);
}
threadPoolExecutor.submit(() -> {
//每次执行的都是0-9个元素
print0(list);
//并发修改异常
copyOnWriteArrayList.removeAll(list);
});
}
}
//迭代器不会报错 但是不能满足多线程批量处理
CopyOnWriteArrayList copyOnWriteArrayList = new CopyOnWriteArrayList(arrayList);
Iterator iterator = copyOnWriteArrayList.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(":::::::::"+next);
copyOnWriteArrayList.remove(next);
}
System.out.println(":::"+JSON.toJSONString(copyOnWriteArrayList));
优化后
static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors(), // 根据 CPU 核心数设置核心线程数
Runtime.getRuntime().availableProcessors() * 2, // 最大线程数设为核心线程数的两倍
100, TimeUnit.SECONDS,
new LinkedBlockingDeque<>(1000), // 调整队列容量
new ThreadPoolExecutor.CallerRunsPolicy());
static Semaphore semaphore = new Semaphore(8);
public static void main(String[] args) {
//多线程并发修改
ArrayList arrayList = new ArrayList();
for (int i = 0; i < 100; i++) {
arrayList.add(i);
}
// ArrayList:
// System.arraycopy
// System.arraycopy(elementData, 0, a, 0, size);
// array.copy 【里面实现使用】浅复制 索引修改后对原数据造成影响【尤其是引用对象】,【建议复制一个新的集合,进行操作,这样两个集合就互不影响了】
//对list操作,就不会影响list0[非引用对象]
// ArrayList list=new ArrayList();
// ArrayList list0=new ArrayList(list);
// CopyOnWriteArrayList
// es = Arrays.copyOf(es, es.length, Object[].class);
CopyOnWriteArrayList copyOnWriteArrayList = new CopyOnWriteArrayList(arrayList);
int batch = 10;
int size = copyOnWriteArrayList.size();
if (0 < size && size <= batch) {
List list = copyOnWriteArrayList.subList(0, size);
threadPoolExecutor.submit(() -> {
log.info(">>>>>>>>>>>>>>:{}", JSON.toJSONString(list));
});
} else {
int flag = size % batch == 0 ? size / batch : size / batch + 1;
for (int i = 0; i < flag; i++) {
List list;
if (i == flag - 1) {
list = copyOnWriteArrayList.subList(i * batch, copyOnWriteArrayList.size());
} else {
list = copyOnWriteArrayList.subList(i * batch, (i + 1) * batch);
}
threadPoolExecutor.submit(() -> {
//每次执行的都是0-9个元素
List<Integer> localCopy = new ArrayList<>(list); // 创建当前批次数据的本地副本
log.info(">>>>>>>>>>>>>>:{}", JSON.toJSONString(localCopy));
//并发修改异常
copyOnWriteArrayList.removeAll(localCopy);
});
}
}
threadPoolExecutor.shutdown();
while (true) {
try {
if (threadPoolExecutor.getActiveCount() == 0 && threadPoolExecutor.getQueue().size() == 0) {
break;
}
Thread.sleep(1000);
log.info("当前活动线程数:{},任务队列剩余任务数:{},已完成任务数:{}",
threadPoolExecutor.getActiveCount(),
threadPoolExecutor.getQueue().size(),
threadPoolExecutor.getCompletedTaskCount());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("线程池等待异常", e);
}
}
}
本文来自博客园,作者:余生请多指教ANT,转载请注明原文链接:https://www.cnblogs.com/wangbiaohistory/p/17578522.html

浙公网安备 33010602011771号