多线程读取文件,map或list存储出现次数,并创建对象封装,最小根堆找出前10个商品
public class Demo { private static final String regex = ","; public static void main(String[] args) throws IOException, InterruptedException { // extracted(); 初始化假数据方法 //核心线程数 int corePoolSize = 3; //等等多线程执行完成 CountDownLatch latch = new CountDownLatch(corePoolSize); //固定线程 线程池 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(0, corePoolSize, 1, TimeUnit.SECONDS, new SynchronousQueue()); //存放id出现的次数 int[] nums = new int[20000]; //并发读取文件 RandomAccessFile rw = new RandomAccessFile("id.txt", "r"); //文件字节大小 long fileLength = rw.length(); //得到多个线程的起始下标 List<Long> offset = getReadLength(corePoolSize, fileLength); offset.add(fileLength); //分成多份处理 for (int i = 0; i < corePoolSize; i++) { final int j = i; threadPoolExecutor.execute(() -> { try { long off = offset.get(j); //TODO 可以继续分N份 每次读取一份 具体分多少份看数据长度 long len = offset.get(j + 1) - off; //读取数据长度 先不考虑数据过大问题 byte[] bytes = new byte[(int) len]; //跳过off个字节 rw.seek(off); rw.read(bytes, 0, bytes.length); String s = new String(bytes, StandardCharsets.UTF_8); String[] split = s.split(regex); Arrays.stream(split).forEach(id -> { synchronized (id){ nums[Integer.parseInt(id)]++; } }); } catch (IOException e) { e.printStackTrace(); }finally { latch.countDown(); } }); } latch.await(); //最大的10个商品id PriorityQueue<Shop> shops = new PriorityQueue<Shop>(10,(x,y)->{ int xCount = x.getCount(); int yCount = y.getCount(); return yCount-xCount; }); for (int i = 0; i < nums.length; i++) { Shop shop = new Shop(i,nums[i]); //添加一个商品 shops.add(shop); //移除一个小的商品 shops.peek(); } for (int i = 0; i < 10; i++) { System.out.println(shops.poll()); } } /** * 保持商品id 和商品出现次数 */ static class Shop{ private Integer id; private int count; public Shop(Integer id, int count) { this.id = id; this.count = count; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } @Override public String toString() { return "Shop{" + "id=" + id + ", count=" + count + '}'; } } /** * 获取多线程多个起始位置 * * @param corePoolSize * @param fileLength * @return 按照线程返回多个起始位置下标 */ private static List<Long> getReadLength(int corePoolSize, long fileLength) { List<Long> list = new ArrayList<>(corePoolSize); //每次读取的长度 long readLength = fileLength / corePoolSize; for (int i = 0; i < corePoolSize; i++) { list.add(i * readLength); } return list; } /** * 初始化数据 * @throws IOException */ private static void extracted() throws IOException { File file = new File("id.txt"); Writer writer = new BufferedWriter(new FileWriter(file)); Random random = new Random(); for (int i = 0; i < 100; i++) { int num = random.nextInt(10); writer.append("" + num + ","); writer.flush(); } writer.close(); }
标签:count,10,重复,public,int,new,corePoolSize,id From: https://www.cnblogs.com/yexuba/p/16587122.html