关于java并发的面试题

发布于 2022-09-01 15:46:59 字数 40 浏览 17 评论 0

10个人同时从10万条数据中取一条数据,要求取到的数据不相同!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

濫情▎り 2022-09-08 15:46:59

把10万个数加上10把区域锁,每个人就限制在该区域拿,就不会重复了,java中有实现的类

苏辞 2022-09-08 15:46:59

1.有两种方法:
10个人按顺序取。当这个人取得时候,其他人不能取(取完设置一个标志位)。
2.同时取,取完再比较。转成hashSet。size不等于10就说明有重复。然后再取一遍。直到不重复。
推荐第一种、

娇女薄笑 2022-09-08 15:46:59

可以试试使用java的并发集合,比如concurrentHashMap等。

皓月长歌 2022-09-08 15:46:59

如果描述的就是全部的要求的话,第X个人取第X条数据不就好了?

只等公子 2022-09-08 15:46:59

BlockingQueue.take()

断舍离 2022-09-08 15:46:59

题主的意思应该是,10个人,随机读取10W条数据,但是必须保证每个人读取的数据是不一样的。比如说A去读取第99条数据这个时候B也读到了第99条数据,这个时候B就必须重新选择一条数据去读取。

我觉得可以在读数据之前先确定读取的是哪条数据,并且把相应的数据行放入一个concurrentHashMap中,下一次读取的时候先判断读取的数据行在Map中是否存在就好了。

月光色 2022-09-08 15:46:59

使用BlockingQueue

白衬杉格子梦 2022-09-08 15:46:59

我的想法是,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();
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文