前言
兄弟篇:Java——使用多线程模拟真实高并发业务并保证安全性(二)
一、需求
使用100个线程往list中添加10000条数据,要求保证安全性,并正确记录数量。
二、实现
在看下面的代码之前,读者朋友可以自己先试一试怎么实现上面的需求,然后跟本文的实现方式对比一下。
2.1 使用技术
可重入锁ReentrantReadWriteLock,这里没有使用到CopyOnWriteArrayList,因为ReentrantReadWriteLock已经起到了CopyOnWriteArrayList对容器add的安全性的同等作用,另外还有对num++的保护。
2.2 实现代码
package com.han.test;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class TestMultiThread {
static List list = new ArrayList();
static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
static int num = 0;
static Random random = new Random();
public static void main(String[] args) {
// 使用100个线程模拟业务,可以根据需要增加或者减少线程数量https://www.szcbjs.com/
for (int i = 0; i < 100; i++) {
new Thread() {
@Override
public void run() {
try {
dosomething();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
}
}
public static void dosomething() throws InterruptedException {
// 设置每个线程最多处理100个数据
int max = 100;
// 使用10000作为测试范围,可以根据需要设置数量
for (int i = 0; list.size() < 10000; i++) {
if (max <= 0) {
break;
}
readWriteLock.writeLock().lock();
if (!list.contains(i)) {
Thread.sleep(random.nextInt(5));
list.add(i);
num++;
max--;
System.out.println(Thread.currentThread().getName() + "***添加了" + num + "个,list数量:" + list.size());
}
readWriteLock.writeLock().unlock();
}
}