java实时处理速度统计的一个方案和例子

这是一个使用Java实现的并发统计缓存类SpeedCache,包含一个统计条数的方法和一个存储速度的方法。同时,有一个SumSpeedTask类用于计算速度,通过对比两次统计之间的数量变化来计算速度,并将结果存储在SpeedCache中。测试用例展示了多个线程并发累加操作以及速度统计任务的执行。
摘要由CSDN通过智能技术生成

单例速度统计缓存类 

package com.qijy.sumspeed;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/*
 * @ Description   :  线程统计缓存
 * @ Author        :  qijy
 * @ CreateDate    :  2020/12/8 10:20
 */
public enum SpeedCache {
    INSTANCE;
    // 数量统计缓存
    private ConcurrentHashMap<String, AtomicLong> speed_count = new ConcurrentHashMap<>();

    private ConcurrentHashMap<String,String> speed = new ConcurrentHashMap<>();
    /*
     * @ Description   :  统计条数
     * @ Author        :  qijy
     * @ CreateDate    :  2020/12/8 10:36
     */
    public void increament(String key){
        if(speed_count.containsKey(key)){
            speed_count.get(key).incrementAndGet();
        }else {
            speed_count.put(key,new AtomicLong(1));
        }
    }
    /*
     * @ Description   :  存储速度
     * @ Author        :  qijy
     * @ CreateDate    :  2020/12/8 10:37
     */
    public void putSpeed(String key,String value){
        speed.put(key,value);
    }

    public ConcurrentHashMap<String,AtomicLong> getSpeed_count(){
        return this.speed_count;
    }

    public ConcurrentHashMap<String,String> getSpeed(){
        return this.speed;
    }

    public void clear(){
        speed_count.clear();
        speed.clear();
    }

}

速度统计任务类:

package com.qijy.sumspeed;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

/*
 * @ Description   :  线程统计任务
 * @ Author        :  qijy
 * @ CreateDate    :  2020/12/8 10:20
 */
public class SumSpeedTask implements Runnable {
    // 上一次时间
    private long pretime;
    // 上一次数量统计
    private ConcurrentHashMap<String, Long> pre_speed_count = new ConcurrentHashMap<>();
    @Override
    public void run() {
        // 当前时间
        long currentTime = System.currentTimeMillis();
        double period = (currentTime - pretime)/1000d;
        ConcurrentHashMap<String, AtomicLong> speed_count = SpeedCache.INSTANCE.getSpeed_count();
        ConcurrentHashMap<String, Long> speed_count_1 = getSpeed_count(speed_count);
        Set<Map.Entry<String, Long>> entries = speed_count_1.entrySet();
        for (Map.Entry<String, Long> entry : entries) {
            String key = entry.getKey();
            Long value = entry.getValue();
            if(speed_count_1.containsKey(key) && this.pre_speed_count.containsKey(key)){
                double v = (value - pre_speed_count.get(key)) / period;
                String format = String.format("%.2f", v);
                if (v>=0){
                    SpeedCache.INSTANCE.putSpeed(key,String.valueOf(format));
                }else {
                    SpeedCache.INSTANCE.putSpeed(key,String.valueOf(0));
                }
            }
        }
        pre_speed_count.putAll(speed_count_1);
        pretime = currentTime;
    }


    private ConcurrentHashMap<String,Long> getSpeed_count(ConcurrentHashMap<String, AtomicLong> speed_count){
        ConcurrentHashMap<String,Long> concurrentHashMap = new ConcurrentHashMap<>();
        for (Map.Entry<String, AtomicLong> entry : speed_count.entrySet()) {
            AtomicLong value = entry.getValue();
            if(value != null){
                concurrentHashMap.put(entry.getKey(),value.get());
            }
        }
        return  concurrentHashMap;
    }
}

 测试用例

package com.qijy.sumspeed;

import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class SumSpeedTest {
    public static void main(String[] args) {
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);
        new Thread(()->{
            while (true){
                try {
                    SpeedCache.INSTANCE.increament("qijy");
                    TimeUnit.MILLISECONDS.sleep(new Random().nextInt(10));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"qijy累加线程").start();

        new Thread(()->{
            while (true){
                try {
                    SpeedCache.INSTANCE.increament("songli");
                    TimeUnit.MILLISECONDS.sleep(new Random().nextInt(20));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        },"songli累加线程").start();
        // 启动速度统计任务
        pool.scheduleAtFixedRate(new SumSpeedTask(),2,2,TimeUnit.SECONDS);

        // 定时清除缓存
        pool.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                SpeedCache.INSTANCE.clear();
            }
        },12,12,TimeUnit.HOURS);
        // 打印速度
        new Thread(()->{
            while(true){
                try {
                    ConcurrentHashMap<String, String> speed = SpeedCache.INSTANCE.getSpeed();
                    for (Map.Entry<String, String> entry : speed.entrySet()) {
                        String key = entry.getKey();
                        String value = entry.getValue();
                        System.out.println(key+"处理速度:"+value);
                    }
                    TimeUnit.MILLISECONDS.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        },"读取速度线程").start();
    }
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个 Java 多线程处理同一批数据的 demo: ```java import java.util.ArrayList; import java.util.List; public class MultiThreadDemo { private static final int THREAD_COUNT = 4; private static final int DATA_SIZE = 1000000; public static void main(String[] args) throws InterruptedException { // 初始化数据 List<Integer> data = new ArrayList<>(DATA_SIZE); for (int i = 0; i < DATA_SIZE; i++) { data.add(i); } // 创建线程 List<Thread> threads = new ArrayList<>(THREAD_COUNT); for (int i = 0; i < THREAD_COUNT; i++) { final int startIndex = i * DATA_SIZE / THREAD_COUNT; final int endIndex = (i + 1) * DATA_SIZE / THREAD_COUNT; Thread thread = new Thread(() -> { // 处理数据 for (int j = startIndex; j < endIndex; j++) { process(data.get(j)); } }); threads.add(thread); } // 启动线程 for (Thread thread : threads) { thread.start(); } // 等待线程执行完成 for (Thread thread : threads) { thread.join(); } // 统计结果 int result = 0; for (int i = 0; i < DATA_SIZE; i++) { result += data.get(i); } System.out.println("Result: " + result); } private static void process(int data) { // TODO: 实现数据处理的逻辑 } } ``` 在这个例子中,我们初始化了一个包含 1000000 个整数的列表,然后创建了 4 个线程来处理这些数据。每个线程处理的数据是均匀分配的,即第 1 个线程处理索引为 0 到 249999 的数据,第 2 个线程处理索引为 250000 到 499999 的数据,以此类推。在每个线程中,我们调用了 `process` 方法来处理数据。 在主线程中,我们启动了所有的线程,并等待它们执行完成。然后我们统计了所有数据的和,输出了结果。 需要注意的是,在多线程处理同一批数据时,需要注意线程之间的同步问题。例如,如果 `process` 方法有副作用,可能会出现数据竞争的问题,导致结果不正确。可以使用 synchronized 或者 Lock 等机制来解决这个问题。 另外,多线程处理同一批数据的效率并不一定比单线程处理快,因为线程之间的切换和同步也会带来一定的开销。因此,在实际应用中,需要根据具体情况来选择最合适的方案
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值