10个人同时从10万条数据中取一条数据,要求取到的数据不相同!
把10万个数加上10把区域锁,每个人就限制在该区域拿,就不会重复了,java中有实现的类
1.有两种方法:10个人按顺序取。当这个人取得时候,其他人不能取(取完设置一个标志位)。2.同时取,取完再比较。转成hashSet。size不等于10就说明有重复。然后再取一遍。直到不重复。推荐第一种、
可以试试使用java的并发集合,比如concurrentHashMap等。
如果描述的就是全部的要求的话,第X个人取第X条数据不就好了?
BlockingQueue.take()
题主的意思应该是,10个人,随机读取10W条数据,但是必须保证每个人读取的数据是不一样的。比如说A去读取第99条数据这个时候B也读到了第99条数据,这个时候B就必须重新选择一条数据去读取。
我觉得可以在读数据之前先确定读取的是哪条数据,并且把相应的数据行放入一个concurrentHashMap中,下一次读取的时候先判断读取的数据行在Map中是否存在就好了。
concurrentHashMap
使用BlockingQueue
我的想法是,N个人从M条(很大)数据中取出数据,要求取到的数据不相同,那么有两个点:一个是存放数据的容器,第二个是如何判重复。为了高并发读取,我考虑是使用一个无锁的数组保存数据,使用一个Atomic指针head控制对数组的并发访问,一个线程需要CAS操作head来获取一个数据,如果判断重复获取过了,就取下一个,抢到资源后Thread.yield()防止有的线程持续执行抢占大量资源(旱的旱死,涝的涝死)。判重可以使用ConcurrentHashMap。写了一个模拟程序如下:
package juc; import java.util.Map; import java.util.Random; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.IntStream; public class QueryMillion { private final static int N = 10; private final static int SIZE = 100000; private final static Data[] dataset; private final static Map<Data, Boolean> map = new ConcurrentHashMap<>(); private final static AtomicInteger head = new AtomicInteger(0); static { Data[] array = new Data[SIZE]; Random random = ThreadLocalRandom.current(); for(int i = 0; i< SIZE; i++){ array[i] = new Data(random.nextInt(SIZE)); } dataset = array; } public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(N); long startMils = System.currentTimeMillis(); IntStream.range(0, N).forEach(i->{ new Thread(()->{ int p; while((p=head.getAndIncrement())<SIZE) { Data userData = dataset[p]; if(!map.containsKey(userData)) { map.put(userData, true); System.out.println(Thread.currentThread().getName() + " get " + userData.hashCode()); Thread.yield(); } } latch.countDown(); },"user-"+i).start(); }); latch.await(); long endMils = System.currentTimeMillis(); System.out.printf("Total cost: %dms\n", (endMils-startMils)); } private static class Data{ private Integer id; public Data(int id){ this.id = id; } @Override public int hashCode(){ return id; } @Override public boolean equals(Object o){ if(o.getClass() != this.getClass()) return false; return o.hashCode() == this.hashCode(); } } }
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
暂无简介
文章 0 评论 0
接受
发布评论
评论(8)
把10万个数加上10把区域锁,每个人就限制在该区域拿,就不会重复了,java中有实现的类
1.有两种方法:
10个人按顺序取。当这个人取得时候,其他人不能取(取完设置一个标志位)。
2.同时取,取完再比较。转成hashSet。size不等于10就说明有重复。然后再取一遍。直到不重复。
推荐第一种、
可以试试使用java的并发集合,比如concurrentHashMap等。
如果描述的就是全部的要求的话,第X个人取第X条数据不就好了?
BlockingQueue.take()
题主的意思应该是,10个人,随机读取10W条数据,但是必须保证每个人读取的数据是不一样的。比如说A去读取第99条数据这个时候B也读到了第99条数据,这个时候B就必须重新选择一条数据去读取。
我觉得可以在读数据之前先确定读取的是哪条数据,并且把相应的数据行放入一个
concurrentHashMap
中,下一次读取的时候先判断读取的数据行在Map中是否存在就好了。使用BlockingQueue
我的想法是,N个人从M条(很大)数据中取出数据,要求取到的数据不相同,那么有两个点:一个是存放数据的容器,第二个是如何判重复。
为了高并发读取,我考虑是使用一个无锁的数组保存数据,使用一个Atomic指针head控制对数组的并发访问,一个线程需要CAS操作head来获取一个数据,如果判断重复获取过了,就取下一个,抢到资源后Thread.yield()防止有的线程持续执行抢占大量资源(旱的旱死,涝的涝死)。判重可以使用ConcurrentHashMap。写了一个模拟程序如下: