同步模式之犹豫模式Balking

简介: 同步模式之犹豫模式Balking是一种多线程编程中的同步模式。在该模式中,线程在执行操作之前会先检查某些条件,如果发现在执行操作之前会导致某些不良后果,则该线程会放弃执行该操作,避免出现问题。

tip: 作为程序员一定学习编程之道,一定要对代码的编写有追求,不能实现就完事了。我们应该让自己写的代码更加优雅,即使这会费时费力。

一、同步模式之犹豫模式Balking

同步模式之犹豫模式Balking是一种多线程编程中的同步模式。在该模式中,线程在执行操作之前会先检查某些条件,如果发现在执行操作之前会导致某些不良后果,则该线程会放弃执行该操作,避免出现问题。

犹豫模式Balking通常用于避免竞态条件和死锁问题。在多线程编程中,由于多个线程同时访问共享资源,可能会导致数据不一致或者死锁等问题。因此,在访问共享资源之前,线程需要先检查某些条件,以确保它们不会破坏共享资源的状态。

例如,如果多个线程都需要向一个队列中添加元素,那么在添加元素之前,每个线程都需要检查队列的状态以确保它们不会重复添加元素。如果某个线程发现队列已经满了,那么它就会放弃添加元素的操作,避免出现死锁或者数据不一致的问题。

总之,同步模式之犹豫模式Balking是一种非常实用的同步模式,可以有效地避免多线程编程中的竞态条件和死锁问题。

二、代码样例

下面是一个实现的同步模式之犹豫模式Balking的例子:
假设有一个多线程程序需要向一个队列中添加元素,但是在添加元素之前需要检查队列是否已经满了。如果队列已经满了,则当前线程需要等待一段时间后再尝试添加元素。

package com.pany.camp.thread.balking;

import cn.hutool.core.thread.ThreadUtil;

import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class BalkingExample {
   
    private final Queue<String> queue = new ConcurrentLinkedQueue<>();
    private final Lock lock = new ReentrantLock();

    public void add(String item) throws InterruptedException {
   
        if (lock.tryLock(1, TimeUnit.SECONDS)) {
   
            try {
   
                if (queue.size() < 5) {
   
                    queue.add(item);
                } else {
   
                    System.out.println("Queue is full. Waiting...");
                    Thread.sleep(1000);
                    add(item);
                }
            } finally {
   
                lock.unlock();
            }
        } else {
   
            System.out.println("Failed to acquire lock. Waiting...");
            Thread.sleep(1000);
            add(item);
        }
    }

    public static void main(String[] args) throws InterruptedException {
   
        BalkingExample example = new BalkingExample();
        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
   
            threads[i] = new Thread(() -> {
   
                try {
   
                    example.add("Thread " + Thread.currentThread().getId());
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
            });
            threads[i].start();
        }
        new Thread(() -> {
   
            ThreadUtil.sleep(1000);
            System.out.println(example.queue);
        }).start();
    }
}

image.png

三、优缺点

犹豫模式Balking虽然可以解决一些同步问题,但也存在一些缺点:

  1. 可能导致死锁:如果一个线程一直在等待某个条件满足,而其他线程也在等待该线程释放锁,这可能会导致死锁。

  2. 可能导致数据丢失:如果一个线程在等待某个条件满足时被中断或终止,那么可能会导致数据丢失。

  3. 可能导致性能问题:如果一个线程一直在等待某个条件满足,那么其他线程可能会被阻塞,从而导致性能问题。
    因此,在使用犹豫模式Balking时,需要仔细考虑其适用性,并确保在使用时避免以上缺点的出现。

目录
相关文章
|
存储 算法 PyTorch
FlashAttention2原理解析以及面向AIGC的加速实践
FlashAttention2原理解析以及面向AIGC的加速实践
2030 0
|
存储 JSON 关系型数据库
基于GeoTools的GeoJson导入到PostGis实战
GeoJson是一种对各种地理数据结构进行编码的格式,基于json的地理空间信息数据交换格式。GeoJson对象可以用来表示几何,特征或者特征集合。支持地理点、线、面、多点、多线、多面及几何集合。GeoJson不是本文的重点,因此不再赘述。
2115 0
基于GeoTools的GeoJson导入到PostGis实战
|
9月前
|
安全 Cloud Native 容灾
海外泼天流量|浅谈全球化技术架构
本文对海外泼天流量现状做了快速整理,旨在抛砖引玉,促进国内企业在出海过程中,交流如何构建全球化技术架构的落地经验,相信会有越来越多资深人士分享更深层次的实践。
436 51
|
3月前
|
NoSQL Redis 数据安全/隐私保护
挂载配置文件以Docker启动Redis服务
以上步骤提供了一个高效且实用的方式来使用Docker启动并运行带有自定义配置的Redis服务。这些操作可以适用于开发、测试和生产环境,是一种灵活且可扩展的部署方案。通过挂载配置文件和数据卷,您可以轻松地管理和迁移您的Redis实例。
406 9
|
10月前
|
JSON 文字识别 API
如何提取手写票据信息
本文主要讲述在处理票据信息结构化提取任务时,如何结合OCR(光学字符识别)技术和多模态大模型Qwen-VL来提高票据信息提取的准确性和效率。
439 17
|
存储 关系型数据库 MySQL
深度剖析:MySQL聚合函数 count(expr) 如何工作?如何选择?
本文详细探讨了MySQL中count(expr)函数的不同形式及其执行效率,包括count(*)、count(1)、count(主键)、count(非主键)等。通过对InnoDB和MyISAM引擎的对比分析,解释了它们在不同场景下的实现原理及性能差异。文章还通过实例演示了事务隔离级别对统计结果的影响,并提供了源码分析和总结建议。适合希望深入了解MySQL统计函数的开发者阅读。
162 0
|
存储 NoSQL Redis
docker搭建Redis Cluster集群环境
docker搭建Redis Cluster集群环境
371 1
|
前端开发 JavaScript 测试技术
"React新手入门的神奇之处:如何用React构建第一个应用,让你的项目一鸣惊人?"
【8月更文挑战第31天】本文详细介绍了如何从头开始构建首个React应用。React作为当今Web开发中备受欢迎的前端框架,采用组件化设计实现界面构建,便于维护与扩展。文章首先解释了React的基础概念,接着演示了使用Create React App搭建项目的步骤,展示了基础组件编写方法及React Router的简单运用,并分享了一些实用的最佳实践建议,帮助读者快速上手React开发。
200 0
|
持续交付 jenkins C#
“WPF与DevOps深度融合:从Jenkins配置到自动化部署全流程解析,助你实现持续集成与持续交付的无缝衔接”
【8月更文挑战第31天】本文详细介绍如何在Windows Presentation Foundation(WPF)项目中应用DevOps实践,实现自动化部署与持续集成。通过具体代码示例和步骤指导,介绍选择Jenkins作为CI/CD工具,结合Git进行源码管理,配置构建任务、触发器、环境、构建步骤、测试及部署等环节,显著提升开发效率和代码质量。
256 0
|
Java Android开发 开发者
17. 【Android教程】开关控件ToggleButton/Switch
17. 【Android教程】开关控件ToggleButton/Switch
407 2