多线程-多个子线程执行结果插入List集合
业务场景:将多个子线程的执行结果存入List,但是总会出现List集合的长度小于子线程的执行数的情况
1、错误示例(多个线程同时操作同一个List对象,List是线程不安全)
package unitTest;
import org.assertj.core.util.Lists;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
// 线程个数
int N = 5;
// 实例化一个倒计数器,N指定计数个数
CountDownLatch countDownLatch = new CountDownLatch(N);
List<Thread> threadList = Lists.newArrayList();
List<String> list = Lists.newArrayList();
// List<String> list = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < N; i++) {
Thread thread = new Thread(()-> {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
list.add(Thread.currentThread().getName());
countDownLatch.countDown();
});
thread.start();
threadList.add(thread);
}
// 阻塞,等待当计数减到0时,执行后面的代码
countDownLatch.await();
System.out.println("线程执行数量: "+threadList.size());
System.out.println("执行结果数量: "+list.size());
}
}
执行结果:



可以看见多次执行结果中,会存在执行结果集合数量小于线程执行总次数的情况
2、正确示例
1.使用Vector,是一个线程安全的List,但是它的线程安全实现方式是对所有操作都加上了synchronized关键字,这种方式严重影响效率.所以并不推荐使用Vector
2.使用 Collections.synchronizedList(List list),可以将add()等方法的时候是加synchronized关键字的,但是iterator()却没有加.所以在遍历使用的时候需要加上synchronized
```java
package unitTest;
import org.assertj.core.util.Lists;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
// 线程个数
int N = 5;
// 实例化一个倒计数器,N指定计数个数
CountDownLatch countDownLatch = new CountDownLatch(N);
List<Thread> threadList = Lists.newArrayList();
// List<String> list = Lists.newArrayList();
List<String> list = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < N; i++) {
Thread thread = new Thread(()-> {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
list.add(Thread.currentThread().getName());
countDownLatch.countDown();
});
thread.start();
threadList.add(thread);
}
// 阻塞,等待当计数减到0时,执行后面的代码
countDownLatch.await();
System.out.println("线程执行数量: "+threadList.size());
System.out.println("执行结果数量: "+list.size());
}
}
执行结果:

可以发现,线程执行数量和执行结果数量相等,这就是线程不安全带来的后果
多线程-多个子线程执行结果插入List集合的更多相关文章
- netframework中等待多个子线程执行完毕并计算执行时间
本文主要描述在.netframework中(实验环境.netframework版本为4.6.1)提供两种方式等待多个子线程执行完毕. ManualResetEvent 在多线程中,将ManualRes ...
- Java多线程理解:线程安全的集合对象
1.概念介绍 线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用.不会出现数据不一致或者数据污染. 线程不安全就 ...
- CountDownLatch用法---等待多个线程执行完才执行
CountDownLatch用法---等待多个线程执行完才执行 CountDownLatch用法---等待多个线程执行完才执行 CountDownLatch用法---等待多个线程执行完才执行 Coun ...
- C# 多线程join的用法,等待多个子线程结束后再执行主线程
等待多个子线程结束后再执行主线程 class MultiThread{ #region join test public void MultiThreadTest() { Thread[] ths = ...
- Java多线程--让主线程等待所有子线程执行完毕
数据量很大百万条记录,因此考虑到要用多线程并发执行,在写的过程中又遇到问题,我想统计所有子进程执行完毕总共的耗时,在第一个子进程创建前记录当前时间用System.currentTimeMillis() ...
- Java多线程--让主线程等待子线程执行完毕
使用Java多线程编程时经常遇到主线程需要等待子线程执行完成以后才能继续执行,那么接下来介绍一种简单的方式使主线程等待. java.util.concurrent.CountDownLatch 使用c ...
- Java多线程——<三>简单的线程执行:Executor
一.概述 按照<Java多线程——<一><二>>中所讲,我们要使用线程,目前都是显示的声明Thread,并调用其start()方法.多线程并行,明显我们需要声明多个 ...
- java多线程实现主线程等待子线程执行完问题
本文介绍两种主线程等待子线程的实现方式,以5个子线程来说明: 1.使用Thread的join()方法,join()方法会阻塞主线程继续向下执行. 2.使用Java.util.concurrent中的C ...
- Java多线程系列四——控制线程执行顺序
假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...
- 【Java多线程系列四】控制线程执行顺序
假设有线程1/线程2/线程3,线程3必须在线程1/线程2执行完成之后开始执行,有两种方式可实现 Thread类的join方法:使宿主线程阻塞指定时间或者直到寄生线程执行完毕 CountDownLatc ...
随机推荐
- STL-RBTree模拟实现
#pragma once #include<assert.h> #include<iostream> using std::cout; using std::endl; usi ...
- git commit大文件后无法删除或撤回
可以使用版本回退的功能 先用git log 查看历史提交 用 git reset --soft 上面的编号 回退到历史提交的版本 再重新commit即可
- centos 磁盘满
1.使用命令:df -lk 找到已满磁盘 2.使用命令:du --max-depth=1 -h 查找大文件,删除
- npm-links - 查看项目依赖包 - vscode 插件
npm-links 依赖包相关快捷链接
- DuiLib 一个window的皮肤库 C++ 项目,打包小,比较纯正主流的大制作
https://github.com/duilib/duilib 从 火柴 那个软件 发现的这个库
- 一个简单的spdlog使用示例
目录 引用源码 封装Log头文件 使用方法 spdlog是一个开源.跨平台.无依赖.只有头文件的C++11日志库,网上介绍的文章有很多这里就不过多的介绍了,GitHub链接:https://githu ...
- IP对讲广播音频模块解决方案
需求分析 随着数字化进程的不断推进,对讲已经覆盖到了各行业各业.并且也逐渐呈现出场景分散化的特点.鉴于此,团队根据市场的变化,及时推出了一款标准化的模块,方便系统集成厂商集成和运用,从而达到节省开 ...
- python下进行10进制转16进制不带0x并且将16进制转成小端序
前记 python涉及到和硬件互交的部分,一般是需要发送十六进制的帧长的.所以,python这个转换还是经常使用的.笔者在这里遇到了一个问题.就做一个记录吧. 基本方法: 假如你熟悉python ...
- .gvfs 文件夹 异常
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- [mysql/docker] 基于Docker安装MYSQL
0 序 虽然关于 mysql 安装的教程,先前已写过很多期了(参见如下列表),但这期的安装教程所依赖的环境还是大有不同的----基于 docker 环境. [数据库] MySQL之数据库备份与升级:M ...