前言
兄弟篇: Java——使用多线程模拟真实高并发业务并保证安全性(一)
一、需求
使用100个线程把一个存放10000条数据的list数据删除,要求保证安全性,并正确记录数量。
二、实现
在看下面的代码之前,读者朋友可以自己先试一试怎么实现上面的需求,然后跟本文的实现方式对比一下。
2.1 使用技术
可重入锁ReentrantReadWriteLock,这里没有使用到CopyOnWriteArrayList,因为ReentrantReadWriteLock已经起到了CopyOnWriteArrayList对容器remove的安全性的同等作用,另外还有对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 TestMultiThread2 { static List<Integer> list = new ArrayList<Integer>(); static ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); static int num = 10000; static Random random = new Random(); public static void main(String[] args) { // 使用10000作为测试范围,可以根据需要设置数量 for (int i = 1; i <= 10000; i++) { list.add(i); } System.out.println("list size: " + list.size()); // 使用10个线程模拟业务,可以根据需要增加或者减少线程数量 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; for (int i = list.size(); list.size() > 0; i--) { if (max <= 0) { break; } readWriteLock.writeLock().lock(); if (list.contains(i)) { Thread.sleep(random.nextInt(5)); list.remove(i - 1); num--; max--; System.out.println(Thread.currentThread().getName() + "***剩余" + num + "个,list数量:" + list.size()); } readWriteLock.writeLock().unlock(); } } }