`

多线程-条件变量: 转自:http://huanyue.javaeye.com/blog/560975

    博客分类:
  • java
阅读更多
条件变量是Java5线程中很重要的一个概念,顾名思义,条件变量就是表示条件的一种变量。但是必须说明,这里的条件是没有实际含义的,仅仅是个标记而已,并且条件的含义往往通过代码来赋予其含义。

这里的条件和普通意义上的条件表达式有着天壤之别。

条件变量都实现了java.util.concurrent.locks.Condition接口,条件变量的实例化是通过一个Lock对象上调用newCondition()方法来获取的,这样,条件就和一个锁对象绑定起来了。因此,Java中的条件变量只能和锁配合使用,来控制并发程序访问竞争资源的安全。

条件变量的出现是为了更精细控制线程等待与唤醒,在Java5之前,线程的等待与唤醒依靠的是Object对象的wait()和notify()/notifyAll()方法,这样的处理不够精细。

而在Java5中,一个锁可以有多个条件,每个条件上可以有多个线程等待,通过调用await()方法,可以让线程在该条件下等待。当调用signalAll()方法,又可以唤醒该条件下的等待的线程。有关Condition接口的API可以具体参考JavaAPI文档。

条件变量比较抽象,原因是他不是自然语言中的条件概念,而是程序控制的一种手段。

下面以一个银行存取款的模拟程序为例来揭盖Java多线程条件变量的神秘面纱:

有一个账户,多个用户(线程)在同时操作这个账户,有的存款有的取款,存款随便存,取款有限制,不能透支,任何试图透支的操作都将等待里面有足够存款才执行操作。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/** 
* Java线程:条件变量 
* 
* @author leizhimin 2009-11-5 10:57:29 
*/ 
public class Test { 
        public static void main(String[] args) { 
                //创建并发访问的账户 
                MyCount myCount = new MyCount("95599200901215522", 10000); 
                //创建一个线程池 
                ExecutorService pool = Executors.newFixedThreadPool(2); 
                Thread t1 = new SaveThread("张三", myCount, 2000); 
                Thread t2 = new SaveThread("李四", myCount, 3600); 
                Thread t3 = new DrawThread("王五", myCount, 2700); 
                Thread t4 = new SaveThread("老张", myCount, 600); 
                Thread t5 = new DrawThread("老牛", myCount, 1300); 
                Thread t6 = new DrawThread("胖子", myCount, 800); 
                //执行各个线程 
                pool.execute(t1); 
                pool.execute(t2); 
                pool.execute(t3); 
                pool.execute(t4); 
                pool.execute(t5); 
                pool.execute(t6); 
                //关闭线程池 
                pool.shutdown(); 
        } 
} 

/** 
* 存款线程类 
*/ 
class SaveThread extends Thread { 
        private String name;                //操作人 
        private MyCount myCount;        //账户 
        private int x;                            //存款金额 

        SaveThread(String name, MyCount myCount, int x) { 
                this.name = name; 
                this.myCount = myCount; 
                this.x = x; 
        } 

        public void run() { 
                myCount.saving(x, name); 
        } 
} 

/** 
* 取款线程类 
*/ 
class DrawThread extends Thread { 
        private String name;                //操作人 
        private MyCount myCount;        //账户 
        private int x;                            //存款金额 

        DrawThread(String name, MyCount myCount, int x) { 
                this.name = name; 
                this.myCount = myCount; 
                this.x = x; 
        } 

        public void run() { 
                myCount.drawing(x, name); 
        } 
} 


/** 
* 普通银行账户,不可透支 
*/ 
class MyCount { 
        private String oid;                         //账号 
        private int cash;                             //账户余额 
        private Lock lock = new ReentrantLock();                //账户锁 
        private Condition _save = lock.newCondition();    //存款条件 
        private Condition _draw = lock.newCondition();    //取款条件 

        MyCount(String oid, int cash) { 
                this.oid = oid; 
                this.cash = cash; 
        } 

        /** 
         * 存款 
         * 
         * @param x        操作金额 
         * @param name 操作人 
         */ 
        public void saving(int x, String name) { 
                lock.lock();                        //获取锁 
                if (x > 0) { 
                        cash += x;                    //存款 
                        System.out.println(name + "存款" + x + ",当前余额为" + cash); 
                } 
                _draw.signalAll();            //唤醒所有等待线程。 
                lock.unlock();                    //释放锁 
        } 

        /** 
         * 取款 
         * 
         * @param x        操作金额 
         * @param name 操作人 
         */ 
        public void drawing(int x, String name) { 
                lock.lock();                                 //获取锁 
                try { 
                        if (cash - x < 0) { 
                                _draw.await();             //阻塞取款操作 
                        } else { 
                                cash -= x;                     //取款 
                                System.out.println(name + "取款" + x + ",当前余额为" + cash); 
                        } 
                        _save.signalAll();             //唤醒所有存款操作 
                } catch (InterruptedException e) { 
                        e.printStackTrace(); 
                } finally { 
                        lock.unlock();                     //释放锁 
                } 
        } 
}

李四存款3600,当前余额为13600 
张三存款2000,当前余额为15600 
老张存款600,当前余额为16200 
老牛取款1300,当前余额为14900 
胖子取款800,当前余额为14100 
王五取款2700,当前余额为11400 

Process finished with exit code 0



假如我们不用锁和条件变量,如何实现此功能呢?下面是实现代码:
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

/** 
* Java线程:不用条件变量 
* 
* @author leizhimin 2009-11-5 10:57:29 
*/ 
public class Test { 
        public static void main(String[] args) { 
                //创建并发访问的账户 
                MyCount myCount = new MyCount("95599200901215522", 10000); 
                //创建一个线程池 
                ExecutorService pool = Executors.newFixedThreadPool(2); 
                Thread t1 = new SaveThread("张三", myCount, 2000); 
                Thread t2 = new SaveThread("李四", myCount, 3600); 
                Thread t3 = new DrawThread("王五", myCount, 2700); 
                Thread t4 = new SaveThread("老张", myCount, 600); 
                Thread t5 = new DrawThread("老牛", myCount, 1300); 
                Thread t6 = new DrawThread("胖子", myCount, 800); 
                //执行各个线程 
                pool.execute(t1); 
                pool.execute(t2); 
                pool.execute(t3); 
                pool.execute(t4); 
                pool.execute(t5); 
                pool.execute(t6); 
                //关闭线程池 
                pool.shutdown(); 
        } 
} 

/** 
* 存款线程类 
*/ 
class SaveThread extends Thread { 
        private String name;                //操作人 
        private MyCount myCount;        //账户 
        private int x;                            //存款金额 

        SaveThread(String name, MyCount myCount, int x) { 
                this.name = name; 
                this.myCount = myCount; 
                this.x = x; 
        } 

        public void run() { 
                myCount.saving(x, name); 
        } 
} 

/** 
* 取款线程类 
*/ 
class DrawThread extends Thread { 
        private String name;                //操作人 
        private MyCount myCount;        //账户 
        private int x;                            //存款金额 

        DrawThread(String name, MyCount myCount, int x) { 
                this.name = name; 
                this.myCount = myCount; 
                this.x = x; 
        } 

        public void run() { 
                myCount.drawing(x, name); 
        } 
} 


/** 
* 普通银行账户,不可透支 
*/ 
class MyCount { 
        private String oid;                         //账号 
        private int cash;                             //账户余额 

        MyCount(String oid, int cash) { 
                this.oid = oid; 
                this.cash = cash; 
        } 

        /** 
         * 存款 
         * 
         * @param x        操作金额 
         * @param name 操作人 
         */ 
        public synchronized void saving(int x, String name) { 
                if (x > 0) { 
                        cash += x;                    //存款 
                        System.out.println(name + "存款" + x + ",当前余额为" + cash); 
                } 
                notifyAll();            //唤醒所有等待线程。 
        } 

        /** 
         * 取款 
         * 
         * @param x        操作金额 
         * @param name 操作人 
         */ 
        public synchronized void drawing(int x, String name) { 
                if (cash - x < 0) { 
                        try { 
                                wait(); 
                        } catch (InterruptedException e1) { 
                                e1.printStackTrace(); 
                        } 
                } else { 
                        cash -= x;                     //取款 
                        System.out.println(name + "取款" + x + ",当前余额为" + cash); 
                } 
                notifyAll();             //唤醒所有存款操作 
        } 
}

李四存款3600,当前余额为13600 
王五取款2700,当前余额为10900 
老张存款600,当前余额为11500 
老牛取款1300,当前余额为10200 
胖子取款800,当前余额为9400 
张三存款2000,当前余额为11400 

Process finished with exit code 0


结合先前同步代码知识,举一反三,将此例改为同步代码块来实现,代码如下:
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

/** 
* Java线程:改为同步代码块 
* 
* @author leizhimin 2009-11-5 10:57:29 
*/ 
public class Test { 
        public static void main(String[] args) { 
                //创建并发访问的账户 
                MyCount myCount = new MyCount("95599200901215522", 10000); 
                //创建一个线程池 
                ExecutorService pool = Executors.newFixedThreadPool(2); 
                Thread t1 = new SaveThread("张三", myCount, 2000); 
                Thread t2 = new SaveThread("李四", myCount, 3600); 
                Thread t3 = new DrawThread("王五", myCount, 2700); 
                Thread t4 = new SaveThread("老张", myCount, 600); 
                Thread t5 = new DrawThread("老牛", myCount, 1300); 
                Thread t6 = new DrawThread("胖子", myCount, 800); 
                //执行各个线程 
                pool.execute(t1); 
                pool.execute(t2); 
                pool.execute(t3); 
                pool.execute(t4); 
                pool.execute(t5); 
                pool.execute(t6); 
                //关闭线程池 
                pool.shutdown(); 
        } 
} 

/** 
* 存款线程类 
*/ 
class SaveThread extends Thread { 
        private String name;                //操作人 
        private MyCount myCount;        //账户 
        private int x;                            //存款金额 

        SaveThread(String name, MyCount myCount, int x) { 
                this.name = name; 
                this.myCount = myCount; 
                this.x = x; 
        } 

        public void run() { 
                myCount.saving(x, name); 
        } 
} 

/** 
* 取款线程类 
*/ 
class DrawThread extends Thread { 
        private String name;                //操作人 
        private MyCount myCount;        //账户 
        private int x;                            //存款金额 

        DrawThread(String name, MyCount myCount, int x) { 
                this.name = name; 
                this.myCount = myCount; 
                this.x = x; 
        } 

        public void run() { 
                myCount.drawing(x, name); 
        } 
} 


/** 
* 普通银行账户,不可透支 
*/ 
class MyCount { 
        private String oid;                         //账号 
        private int cash;                             //账户余额 

        MyCount(String oid, int cash) { 
                this.oid = oid; 
                this.cash = cash; 
        } 

        /** 
         * 存款 
         * 
         * @param x        操作金额 
         * @param name 操作人 
         */ 
        public void saving(int x, String name) { 
                if (x > 0) { 
                        synchronized (this) { 
                                cash += x;                    //存款 
                                System.out.println(name + "存款" + x + ",当前余额为" + cash); 
                                notifyAll();            //唤醒所有等待线程。 
                        } 
                } 
        } 

        /** 
         * 取款 
         * 
         * @param x        操作金额 
         * @param name 操作人 
         */ 
        public synchronized void drawing(int x, String name) { 
                synchronized (this) { 
                        if (cash - x < 0) { 
                                try { 
                                        wait(); 
                                } catch (InterruptedException e1) { 
                                        e1.printStackTrace(); 
                                } 
                        } else { 
                                cash -= x;                     //取款 
                                System.out.println(name + "取款" + x + ",当前余额为" + cash); 
                        } 
                } 
                notifyAll();             //唤醒所有存款操作 
        } 
}

李四存款3600,当前余额为13600 
王五取款2700,当前余额为10900 
老张存款600,当前余额为11500 
老牛取款1300,当前余额为10200 
胖子取款800,当前余额为9400 
张三存款2000,当前余额为11400 

Process finished with exit code 0
分享到:
评论

相关推荐

    UltraEdit Skill

    NULL 博文链接:https://huanyue.iteye.com/blog/1223174

    Java中文件的压缩

    NULL 博文链接:https://huanyue.iteye.com/blog/371973

    浙江大学2025年DeepSeek的本地化部署与AI通识教育之未来57页.pdf

    浙江大学2025年DeepSeek的本地化部署与AI通识教育之未来57页.pdf

    基于Matlab+YALMIP+CPLEX的社区综合能源系统主从博弈分布式协同优化策略

    内容概要:本文探讨了基于主从博弈理论的社区综合能源系统分布式协同优化运行策略。随着能源市场的变化,传统的集中优化方法已无法满足多主体间的复杂交互需求。文中利用Matlab、YALMIP和CPLEX平台,构建了一主多从的分布式协同优化模型,其中综合能源销售商作为领导者,新能源冷热电联供运营商和负荷聚合商作为跟随者。通过遗传算法和二次规划相结合的方式解决了Stackelberg均衡的唯一性和求解问题,并通过多个算例验证了该策略的有效性。结果显示,该策略显著提高了供能侧的收益和用能侧的消费者剩余。 适合人群:对能源系统优化、博弈论及其应用感兴趣的科研人员和技术开发者。 使用场景及目标:适用于研究和实施社区综合能源系统的分布式协同优化,旨在提高能源系统的经济效益和社会效益。 其他说明:文中提供了详细的模型构建步骤、代码示例和实验结果,有助于理解和复现实验过程。此外,讨论了光伏渗透率对博弈策略的影响,强调了收敛条件设置的重要性,并分享了一些实用的技术技巧。

    nexus-3.77.2-02-java17-win64.zip

    nexus-3.77版本,适用于windows环境下本地仓库环境搭建,支持jdk17以上,支持https访问配置

    matlab-使用可再生能源的能量存储系统

    该MATLAB Simulink模型提供了与太阳能集成的储能系统(ESS)的综合仿真。该模型是为旨在探索、研究或原型可再生能源解决方案的用户设计的。它包括模拟太阳能发电、电池存储和并网或独立系统的能源管理的组件。太阳能电池板的输入电压可以根据用户而改变 特征 太阳能发电:模拟具有不同太阳辐照度的光伏(PV)系统。 两个储能系统的集成:引入两个动态储能系统来储存能量,它们是锂离子电池和超级电容电池。超级电容器电池被引入来处理由可再生能源引起的波动,锂离子电池被用于支持电网 电池储能:为锂离子电池和超级电容电池实施高效的充电和放电机制 能量管理系统(EMS):平衡光伏系统、电池和负载之间的能量流动。 负载动力学:支持可变负载条件,以测试系统的健壮性。 用户友好的设计:模块化和可定制的模型架构,易于适应。 应用程序 可再生能源的电网整合。 离网储能系统的开发。 理解ESS和太阳能概念的教育目的。 可再生能源技术的研究和开发。

    材料科学中COMSOL与Avizo联合仿真的数字岩心流固耦合建模及其应用

    内容概要:本文详细介绍了利用COMSOL Multiphysics和Avizo软件进行数字岩心建模和流固耦合模拟的方法和技术细节。首先阐述了数字岩心的概念及其重要性,接着讲解了如何在COMSOL中构建流固耦合模型,包括定义物理场、设置参数以及生成高质量网格。随后讨论了Avizo在处理CT扫描图像方面的优势,展示了如何通过Python脚本实现图像分割和三维模型生成,并将其与COMSOL结合用于更精准的物理场模拟。最后强调了这种联合仿真技术在地质工程和能源勘探中的广泛应用前景。 适合人群:从事材料科学研究、地质工程、石油天然气勘探等相关领域的研究人员和技术人员。 使用场景及目标:适用于需要深入了解岩石内部流体流动特性和传输性质的研究项目,旨在提升对复杂地质结构的认识并优化资源开采过程。 其他说明:文中提供了大量实用的技术细节和代码片段,帮助读者更好地理解和实施具体的仿真步骤。同时提醒了一些常见的陷阱和解决方案,有助于提高工作效率和准确性。

    基于51单片机protues仿真的水泵效率温差法测量系统(仿真图、源代码、AD原理图)

    基于51单片机protues仿真的水泵效率温差法测量系统(仿真图、源代码、AD原理图) 水泵效率温差法测量系统 主要是用两个E型热电偶测量水泵进出口温差,温差传给单片机(有水泵效率的经验公式)用单片机程序算出效率并显示出来 主要硬件是两个E型热电偶,好像是分别接MAX31855芯片通信到AT89C52,然后通过单片机编程算出效率再显示效率 设置效率的范围 要是超出范围就报警 1、E型热电偶测量水泵进出口温差; 2、MAX31855芯片温度采集; 3、按键设置温度参数; 4、LCD液晶屏显示相关参数和信息; 5、计算显示效率;

    基于TCN时间卷积神经网络的多分类预测:Excel数据驱动的高精度解决方案

    内容概要:本文详细介绍了基于时间卷积神经网络(TCN)的多分类预测方法,旨在提高时间序列数据分类的准确性。首先简述了TCN的基本原理及其相对于传统循环神经网络(如LSTM、GRU)的独特优势,特别是在并行计算和长期依赖处理方面。接着,文章展示了从Excel中读取数据的具体步骤,并进行了必要的数据预处理,如特征缩放和标签编码。随后,构建了一个基于Keras框架的TCN模型,详细解释了每一层的作用以及参数设置的理由。为了确保模型的有效性和泛化能力,文中还讨论了数据集的划分方式、训练技巧(如滑窗划分)、模型评估指标(如混淆矩阵)以及最终的模型部署方法。此外,作者分享了一些实用的经验和技巧,如避免梯度爆炸的方法、调整学习率策略等。 适合人群:对时间序列数据分析感兴趣的初学者和有一定经验的数据科学家,尤其是希望深入了解TCN模型及其应用的人群。 使用场景及目标:本方案适用于各种涉及时间序列分类的任务,如金融市场趋势预测、工业设备故障检测等。目标是在保证高准确度的同时,提供灵活易用的实现方式,使用户能够快速上手并在自己的项目中应用。 其他说明:文中提供的代码片段可以直接运行或稍作修改后应用于不同的数据集。对于想要进一步优化模型性能的研究者来说,文中提到的一些高级技巧(如滑窗划分、自定义损失函数等)也非常有价值。

    ESP32远程OTA升级解决方案:自动回滚与Websocket传输优化

    内容概要:本文介绍了一种针对ESP32设备的改进型OTA(Over-The-Air)固件升级方案。该方案不仅解决了官方OTA示例中存在的问题,如手动模式灵活性差、自动模式易变砖以及错误处理不足,还增加了自动回滚机制、Websocket传输协议、双模切换等功能。文中详细展示了如何通过SPIFFS存储固件MD5值进行校验,确保固件完整性;利用Websocket提高传输效率并实现断点续传;并通过NVS闪存保存启动计数,增强系统的容错能力。此外,作者分享了实际应用案例,如智能家居项目的批量升级和工业设备的稳定性测试。 适合人群:对ESP32有初步了解并希望深入研究OTA升级机制的开发者和技术爱好者。 使用场景及目标:适用于需要频繁更新固件的物联网设备,特别是那些部署于难以物理接触的位置或者对可靠性要求较高的场合。主要目标是提供一种更加稳定、高效的OTA升级方法,减少因升级失败而导致设备无法使用的风险。 其他说明:文中提供了完整的代码片段和配置指导,帮助读者快速理解和应用这一方案。同时强调了在不同网络环境下的适应性和鲁棒性,确保即使在网络不稳定的情况下也能顺利完成升级。

    光子晶体超表面中动量空间动态调节BICs的COMSOL模拟及其应用

    内容概要:本文详细探讨了光子晶体超表面中动量空间动态调节BICs(连续域中的束缚态)的技术和方法。首先介绍了动量空间和BICs的基础概念,解释了BICs作为一种特殊光学模式的独特性质。随后讨论了通过改变几何参数或引入外部激励来动态调节BICs的具体方法,并展示了如何利用COMSOL软件进行模拟。文中提供了具体的COMSOL建模步骤和脚本示例,包括几何模型的创建、材料属性的设置、物理场的选择以及参数化的扫描设置。此外,还分享了一些实际操作中的经验和技巧,如如何处理COMSOL的缓存问题、优化网格划分、监测Q值变化等。最后,强调了这种结合理论与模拟的研究方法在新型光学器件设计和光与物质相互作用新机制探索中的重要性和有效性。 适合人群:从事光子学、光学工程、物理学等相关领域的研究人员和技术人员,尤其是对光子晶体超表面和BICs感兴趣的学者。 使用场景及目标:适用于希望通过理论结合模拟深入理解光子晶体中超表面BICs特性的科研工作者。主要目标是掌握动量空间中动态调节BICs的方法,为设计高性能光学器件提供理论支持和技术手段。 其他说明:文章不仅提供了详细的理论推导和公式解析,还包括了大量的COMSOL建模实例和代码片段,便于读者动手实践。同时,文中提到了许多实际操作中的注意事项和经验教训,有助于提高模拟效率和准确性。

    如何综合性测试一款电源芯片?ASP3605芯片测试报告

    如何综合性测试一款电源芯片?ASP3605芯片测试报告

    SVM-Adaboost多分类预测算法在MATLAB平台上的故障识别与诊断应用

    内容概要:本文介绍了SVM-Adaboost算法及其在MATLAB平台上的实现方法,重点探讨了该算法在多种故障识别场景中的应用。SVM-Adaboost结合了支持向量机的强大分类能力与Adaboost的迭代增强特性,适用于多分类问题。文中详细讲解了轴承故障识别、变压器油气故障识别、输电线路故障区域识别和绝缘子、配网故障识别的具体实现步骤,包括数据读取、预处理、模型训练、预测验证等环节。此外,还提供了具体的MATLAB代码示例,展示了如何通过调整样本权重、选择合适的核函数等方式优化模型性能。 适合人群:具有一定MATLAB编程基础和技术背景的研究人员、工程师,特别是从事机械故障诊断、电力系统维护等相关工作的专业人员。 使用场景及目标:①快速准确地识别机械设备如轴承、变压器等的故障类型;②提高电力系统输电线路故障区域的定位精度;③增强绝缘子、配网故障识别的准确性;④通过优化模型参数,提升故障识别的效率和可靠性。 其他说明:文章强调了SVM-Adaboost算法在处理小样本数据方面的优势,并指出了一些常见的注意事项,如样本类别均衡、核函数选择、Adaboost迭代次数等。同时,提供了实用的代码片段和技巧,帮助读者更好地理解和应用该算法。

    S7-200 Smart PLC用于卷板材生产线及造纸设备的速度与频率同步控制程序解析

    内容概要:本文详细介绍了基于S7-200 Smart PLC的速度与频率同步控制程序,主要用于卷板材生产线和造纸设备。程序通过设置速度同步地址vw10作为基准,利用频率调整系数factor[i]实现1-15回路的频率同步。此外,还支持主从单机微调功能,确保各回路能够精确同步。文中提供了具体的代码示例,解释了如何通过简单逻辑实现多机同步,并强调了微调和异常检测的重要性。对于16-30回路,考虑到设备布局和负载差异,提出了相应的优化建议,如地址映射调整和滤波算法的应用。 适合人群:从事自动化控制系统开发的技术人员,尤其是熟悉PLC编程和变频器应用的专业人士。 使用场景及目标:①帮助技术人员理解和掌握S7-200 Smart PLC在卷板材生产线和造纸设备中的速度与频率同步控制方法;②提供实用的代码示例和技术细节,便于快速部署和调试;③提高生产线的稳定性和效率,降低故障发生率。 其他说明:本文不仅涵盖了基本的同步控制逻辑,还包括了许多实际应用中的经验和技巧,如微调处理、异常检测和滤波算法等,有助于解决实际工程中的常见问题。

    WPF 全局右键上下文菜单样式, 以及命令的绑定MVVM

    windows系统 的右键菜单太丑有没有, 替换自定义的菜单要是应用不到全局,你就可以来看看, 还写了命令绑定, mvvm模式的.示例代码

    -函数复习整理笔记思维导图还是脑图

    学习

    基于梯度下降的改进自适应短时傅里叶变换方法及其在Jupyter Notebook中的应用

    内容概要:本文介绍了基于梯度下降的改进自适应短时傅里叶变换(STFT)方法,并展示了其在Jupyter Notebook中的具体实现。传统的STFT由于固定窗口长度,在处理非平稳信号时存在局限性。改进的方法通过梯度下降策略自适应调整窗口参数,从而提高时频分辨率。文中详细解释了算法的工作原理,包括信号生成、窗函数设计、损失函数选择等方面,并给出了具体的Python代码示例。此外,文章还讨论了该方法在多个领域的广泛应用,如金融时间序列、地震信号、机械振动信号、声发射信号、电压电流信号、语音信号、声信号和生理信号等。 适合人群:从事信号处理、数据分析及相关领域研究的专业人士,尤其是对时频分析感兴趣的科研人员和技术开发者。 使用场景及目标:适用于需要处理非平稳信号的研究和应用场景,旨在提高信号处理的精度和效率。具体目标包括但不限于:改善金融市场的预测能力、提升地震监测系统的准确性、增强机械设备故障诊断的效果、优化语音识别和合成的质量等。 其他说明:该方法不仅限于特定类型的信号,而是可以通过调整参数灵活应用于不同的信号类型。文中提供的代码可以在Jupyter Notebook环境中直接运行,便于实验和验证。

    蓝桥杯python官方省赛模拟题源代码

    蓝桥杯python资源。蓝桥杯python官方省赛模拟题源代码。

    使用遗传算法的示例问题和解决方案

    使用遗传算法的示例问题和解决方案 给定一个目标字符串,目标是从相同长度的随机字符串开始生成目标字符串。在下面的实施中,进行了以下类比 - 字符 A-Z、a-z、0-9 和其他特殊符号被视为基因 由这些字符生成的字符串被视为 chromosome/solution/Individual 适应度分数是特定索引处与目标字符串中的字符不同的字符数。因此,体能值较低的个体被赋予更多的优先权。 // Number of individuals in each generation

    2025.2.8钟阜路走访人员名单.lnk

    2025.2.8钟阜路走访人员名单.lnk

Global site tag (gtag.js) - Google Analytics