0

0

探索Java中的限制

尊渡假赌尊渡假赌尊渡假赌

尊渡假赌尊渡假赌尊渡假赌

发布时间:2024-01-02 10:28:41

|

1602人浏览过

|

来源于dzone

转载

在软件开发领域,有效管理资源消耗和确保公平使用服务是构建可扩展且健壮的应用程序的重要考虑因素。节流是控制某些操作执行速率的做法,是实现这些目标的关键机制。在本文中,我们将深入探讨在Java中实现节流的各种方法,并通过实际示例介绍各种策略。

探索Java中的限制

探索 Java 中的限制:简单实现示例 - 第 1 部分

有效管理资源消耗和确保服务的公平使用是构建可扩展且健壮的应用程序的重要考虑因素。

在软件开发领域,有效管理资源消耗和确保公平使用服务是构建可扩展且健壮的应用程序的重要考虑因素。节流是控制某些操作执行速率的做法,是实现这些目标的关键机制。在本文中,我们将深入探讨在 Java 中实现节流的各种方法,并通过实际示例介绍各种策略。

免責聲明:在本文中,我将重点介绍简单的单线程插图,以解决基本方案。

了解限制

限制涉及调节允许某些操作发生的频率。这在系统需要防止滥用、需要资源管理或需要公平访问共享服务的情况下尤为重要。限制的常见用例包括限制 API 请求的速率、管理数据更新以及控制对关键资源的访问。

简单的阻塞速率限制器 - 不用于生产!thread.sleep()

实现限制的一种简单方法是使用该方法在连续操作之间引入延迟。虽然此方法很简单,但由于其阻塞性,它可能不适合高性能方案。Thread.sleep()

public class SimpleRateLimiter {

    private long lastExecutionTime = 0;
    private long intervalInMillis;

    public SimpleRateLimiter(long requestsPerSecond) {
        this.intervalInMillis = 1000 / requestsPerSecond;
    }

    public void throttle() throws InterruptedException {
        long currentTime = System.currentTimeMillis();
        long elapsedTime = currentTime - lastExecutionTime;

        if (elapsedTime < intervalInMillis) {
            Thread.sleep(intervalInMillis - elapsedTime);
        }

        lastExecutionTime = System.currentTimeMillis();
        // Perform the throttled operation
        System.out.println("Throttled operation executed at: " + lastExecutionTime);
    }
}

在此示例中,该类允许每秒执行指定数量的操作。如果操作之间经过的时间小于配置的时间间隔,则会引入睡眠持续时间以达到所需的速率。SimpleRateLimiter

等待的基本限制

让我们从一个简单的示例开始,我们用它来限制方法的执行。目标是允许仅在经过特定冷却时间后调用该方法。wait

立即学习Java免费学习笔记(深入)”;

public class BasicThrottling {

    private final Object lock = new Object();
    private long lastExecutionTime = 0;
    private final long cooldownMillis = 5000; // 5 seconds cooldown

    public void throttledOperation() throws InterruptedException {
        synchronized (lock) {
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - lastExecutionTime;

            if (elapsedTime < cooldownMillis) {
                lock.wait(cooldownMillis - elapsedTime);
            }

            lastExecutionTime = System.currentTimeMillis();
            // Perform the throttled operation
            System.out.println("Throttled operation executed at: " + lastExecutionTime);
        }
    }
}

在此示例中,该方法使用该方法使线程等待冷却时间结束。throttledOperationwait

具有等待和通知的动态限制

让我们对前面的示例进行增强,以引入动态节流,其中冷却时间可以动态调整。生产必须有机会在飞行中做出改变。

public class DynamicThrottling {

    private final Object lock = new Object();
    private long lastExecutionTime = 0;
    private long cooldownMillis = 5000; // Initial cooldown: 5 seconds

    public void throttledOperation() throws InterruptedException {
        synchronized (lock) {
            long currentTime = System.currentTimeMillis();
            long elapsedTime = currentTime - lastExecutionTime;

            if (elapsedTime < cooldownMillis) {
                lock.wait(cooldownMillis - elapsedTime);
            }

            lastExecutionTime = System.currentTimeMillis();
            // Perform the throttled operation
            System.out.println("Throttled operation executed at: " + lastExecutionTime);
        }
    }

    public void setCooldown(long cooldownMillis) {
        synchronized (lock) {
            this.cooldownMillis = cooldownMillis;
            lock.notify(); // Notify waiting threads that cooldown has changed
        }
    }

    public static void main(String[] args) {
        DynamicThrottling throttling = new DynamicThrottling();

        for (int i = 0; i < 10; i++) {
            try {
                throttling.throttledOperation();
                // Adjust cooldown dynamically
                throttling.setCooldown((i + 1) * 1000); // Cooldown increases each iteration
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在本例中,我们介绍了动态调整冷却时间的方法。该方法用于唤醒任何等待的线程,允许它们检查新的冷却时间。setCooldownnotify

使用 Java 的信号量

Java 的类可以用作节流的强大工具。信号量维护一组许可证,其中每个获取操作消耗一个许可证,每个释放操作增加一个许可证。Semaphore

AIBox 一站式AI创作平台
AIBox 一站式AI创作平台

AIBox365一站式AI创作平台,支持ChatGPT、GPT4、Claue3、Gemini、Midjourney等国内外大模型

下载
public class SemaphoreRateLimiter {

    private final Semaphore semaphore;

    public SemaphoreRateLimiter(int permits) {
        this.semaphore = new Semaphore(permits);
    }

    public boolean throttle() {
        if (semaphore.tryAcquire()) {
            // Perform the throttled operation
            System.out.println("Throttled operation executed. Permits left: " + semaphore.availablePermits());
            return true;
        } else {
            System.out.println("Request throttled. Try again later.");
            return false;
        }
    }

    public static void main(String[] args) {
        SemaphoreRateLimiter rateLimiter = new SemaphoreRateLimiter(5); // Allow 5 operations concurrently

        for (int i = 0; i < 10; i++) {
            rateLimiter.throttle();
        }
    }
}

在此示例中,该类使用具有指定数量许可的 a。该方法尝试获取许可证,并在成功时允许该操作。SemaphoreRateLimiterSemaphorethrottle

盒子里的多个例子

Spring 或 Redis 等框架提供了多种简单的解决方案。

Spring AOP 用于方法限制

使用 Spring 的面向方面的编程 (AOP) 功能,我们可以创建一个方法级限制机制。这种方法允许我们拦截方法调用并应用限制逻辑。

@Aspect
@Component
public class ThrottleAspect {

    private Map<String, Long> lastInvocationMap = new HashMap<>();

    @Pointcut("@annotation(throttle)")
    public void throttledOperation(Throttle throttle) {}

    @Around("throttledOperation(throttle)")
    public Object throttleOperation(ProceedingJoinPoint joinPoint, Throttle throttle) throws Throwable {
        String key = joinPoint.getSignature().toLongString();

        if (!lastInvocationMap.containsKey(key) || System.currentTimeMillis() - lastInvocationMap.get(key) > throttle.value()) {
            lastInvocationMap.put(key, System.currentTimeMillis());
            return joinPoint.proceed();
        } else {
            throw new ThrottleException("Request throttled. Try again later.");
        }
    }
}

在此示例中,我们定义了一个自定义注释和一个 AOP 方面 () 来拦截用 .检查自上次调用以来经过的时间,并相应地允许或阻止该方法。@ThrottleThrottleAspect@ThrottleThrottleAspect

使用 Guava RateLimiter

Google 的 Guava 库提供了一个简化限制实现的类。它允许定义允许操作的速率。RateLimiter

让我们看看如何用于方法限制:RateLimiter

import com.google.common.util.concurrent.RateLimiter;

@Component
public class ThrottledService {

    private final RateLimiter rateLimiter = RateLimiter.create(5.0); // Allow 5 operations per second

    @Throttle
    public void throttledOperation() {
        if (rateLimiter.tryAcquire()) {
            // Perform the throttled operation
            System.out.println("Throttled operation executed.");
        } else {
            throw new ThrottleException("Request throttled. Try again later.");
        }
    }
}

在此示例中,我们使用 Guava 来控制方法的执行速率。该方法用于根据定义的速率检查是否允许操作。RateLimiterthrottledOperationtryAcquire

Redis 作为限制机制

使用像 Redis 这样的外部数据存储,我们可以实现分布式节流机制。此方法在需要多个实例协调限制的微服务环境中特别有用。

@Component
public class RedisThrottleService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${throttle.key.prefix}")
    private String keyPrefix;

    @Value("${throttle.max.operations}")
    private int maxOperations;

    @Value("${throttle.duration.seconds}")
    private int durationSeconds;

    public void performThrottledOperation(String userId) {
        String key = keyPrefix + userId;
        Long currentCount = redisTemplate.opsForValue().increment(key);

        if (currentCount != null && currentCount > maxOperations) {
            throw new ThrottleException("Request throttled. Try again later.");
        }

        if (currentCount == 1) {
            // Set expiration for the key
            redisTemplate.expire(key, durationSeconds, TimeUnit.SECONDS);
        }

        // Perform the throttled operation
        System.out.println("Throttled operation executed for user: " + userId);
    }
}

在此示例中,我们使用 Redis 来存储和管理每个用户的操作计数。该方法递增计数,并检查是否已达到允许的限制。performThrottledOperation

结论

限制在维护应用程序的稳定性和可伸缩性方面起着关键作用。在本文中,我们探讨了在 Java 中实现节流的各种方法,包括使用和应用开箱即用解决方案的简单技术。Thread.sleep()Semaphore

限制策略的选择取决于应用程序的性质、性能要求和所需的控制级别等因素。实施限制时,必须在防止滥用和确保响应迅速且公平的用户体验之间取得平衡。

将限制机制集成到应用程序中时,请考虑根据实际使用模式监视和调整参数。在决定限制实现时,可能会出现一些查询,例如如何处理任务超过分配期限的情况。在下一篇文章中,我计划探索能够全面解决各种场景的健壮的 Java 实现。

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

161

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

89

2026.01.26

什么是分布式
什么是分布式

分布式是一种计算和数据处理的方式,将计算任务或数据分散到多个计算机或节点中进行处理。本专题为大家提供分布式相关的文章、下载、课程内容,供大家免费下载体验。

411

2023.08.11

分布式和微服务的区别
分布式和微服务的区别

分布式和微服务的区别在定义和概念、设计思想、粒度和复杂性、服务边界和自治性、技术栈和部署方式等。本专题为大家提供分布式和微服务相关的文章、下载、课程内容,供大家免费下载体验。

251

2023.10.07

guava包作用
guava包作用

guava是一个java库,增强了java标准库,提供更有效率和易于使用的集合、实用程序、缓存和并发工具。想了解更多guava的相关内容,可以阅读本专题下面的文章。

271

2024.05.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

766

2023.08.10

Java 并发编程高级实践
Java 并发编程高级实践

本专题深入讲解 Java 在高并发开发中的核心技术,涵盖线程模型、Thread 与 Runnable、Lock 与 synchronized、原子类、并发容器、线程池(Executor 框架)、阻塞队列、并发工具类(CountDownLatch、Semaphore)、以及高并发系统设计中的关键策略。通过实战案例帮助学习者全面掌握构建高性能并发应用的工程能力。

100

2025.12.01

常用的数据库软件
常用的数据库软件

常用的数据库软件有MySQL、Oracle、SQL Server、PostgreSQL、MongoDB、Redis、Cassandra、Hadoop、Spark和Amazon DynamoDB。更多关于数据库软件的内容详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1007

2023.11.02

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.4万人学习

C# 教程
C# 教程

共94课时 | 11.3万人学习

Java 教程
Java 教程

共578课时 | 81.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号