一、前言
一般而言,想要构造出线程安全的 Set,我们会使用 Collections.synchronizedSet 方法,如下所示。
Set<User> set = Collections.synchronizedSet(new HashSet<>());
但这并不意味着,你可以安全的使用该集合的任何方法,如果没有仔细的了解过其实现的话,一不小心就会踩进坑中。
最近我在使用该集合的 stream 方法时发现了线程不安全问题,都是血的教训啊,下面写个Case 来复现下吧。
二、问题引出
2.1 辅助类
本 Case 牵扯到的所有辅助类如下:
public class ThreadPoolUtils {
private static final long KEEP_ALIVE_TIME = 60L;
private static Logger log = LogManager.getLogger(ThreadPoolUtils.class);
public static ThreadPoolExecutor poolExecutor(int core, int max, Object... name) {
ThreadFactory factory = Objects.nonNull(name) ?
new ThreadFactoryBuilder().setNameFormat(Joiner.on(" ").join(name)).build() :
new ThreadFactoryBuilder().build();
return new ThreadPoolExecutor(core, max, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), factory,
new ThreadPoolExecutor.AbortPolicy());
}
public static void sleep(long timeout, TimeUnit unit) {
try {
unit.sleep(timeout);
} catch (InterruptedException e) {
log.info("ThreadPoolUtils#sleep error, timeout: {}", timeout, e);
}
}
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
private

最低0.47元/天 解锁文章
1860

被折叠的 条评论
为什么被折叠?



