Java多线程--同步机制解决线程安全问题方式二:同步方法

文章目录

  • 一、同步方法
    • (1)同步方法--案例1
      • 1、案例1
      • 2、案例1之同步监视器
    • (2)同步方法--案例2
      • 1、案例2之同步监视器的问题
      • 2、案例2的补充说明
  • 二、代码及重要说明
    • (1)代码
    • (2)重要说明

一、同步方法

同步方法:synchronized 关键字直接修饰方法,表示同一时刻只有一个线程能进入这个方法,其他线程在外面等着

🗳️格式:

public synchronized void method(){
    可能会产生线程安全问题的代码
}

(1)同步方法–案例1

1、案例1

还是拿这个例子来说,方式一实现Runnable接口,如下:

🌱代码

package yuyi02;

/**
 * ClassName: WindowTset2
 * Package: yuyi02
 * Description:
 *		使用同步方法解决实现Runnable接口的线程安全问题
 * @Author 雨翼轻尘
 * @Create 2024/1/30 0030 9:52
 */
public class WindowTest2 {
    public static void main(String[] args) {
        //3.创建当前实现类的对象
        SaleTicket2 s=new SaleTicket2();

        //4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
        Thread t1 = new Thread(s);
        Thread t2 = new Thread(s);
        Thread t3 = new Thread(s);

        //给三个线程起名字
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        //5.通过Thread类的实例调用start():1.启动线程 2.调用当前线程的run()。
        t1.start();
        t2.start();
        t3.start();
    }
}

class SaleTicket2 implements Runnable{   //卖票    1.创建一个实现Runnable接口的类(实现类)
    int ticket=100;
    @Override
    public void run() { //2.实现接口中的抽象方法run()方法
        while (true){
            if(ticket>0){   //如果票数大于0就可以售票
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //哪个窗口卖票了,票卖了多少
                System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);  //最开始票号为100
                ticket--;
            }else{
                break;
            }
        }
    }
}

🍺输出结果(部分)

image.png

可以看到,出现了重票和错票


现在来解决这个安全问题。

操作ticket的代码:

image.png

现在将他们完全声明在一个方法show()当中,然后在while里面调用show()方法。比如:

image.png

我们可以将while里面的show()synchronized包裹,就是同步代码块的方式,如下:

public void run() { //2.实现接口中的抽象方法run()方法
    while (true){
        synchronized (this) {
            show();
        }
    }
}

当然也可以将show方法声明为同步方法

现在这里有点错误,就是break的问题。之前是在while里面写的,现在将if-else从while里面抽出来了,所以break就不行了。
将break直接删掉吗?不行,这样的话程序就不能自己结束了。如下:

image.png

我们可以声明一个变量isFlag,初始化为true。如下:

image.png

🌱代码

public class WindowTest2 {
    public static void main(String[] args) {
        //3.创建当前实现类的对象
        SaleTicket2 s=new SaleTicket2();

        //4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
        Thread t1 = new Thread(s);
        Thread t2 = new Thread(s);
        Thread t3 = new Thread(s);

        //给三个线程起名字
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        //5.通过Thread类的实例调用start():1.启动线程 2.调用当前线程的run()。
        t1.start();
        t2.start();
        t3.start();
    }
}

class SaleTicket2 implements Runnable{   //卖票    1.创建一个实现Runnable接口的类(实现类)
    int ticket=100;
    boolean isFlag=true;
    public void show(){
        if(ticket>0){   //如果票数大于0就可以售票
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //哪个窗口卖票了,票卖了多少
            System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);  //最开始票号为100
            ticket--;
        }else{
            isFlag=false;
        }
    }
    @Override
    public void run() { //2.实现接口中的抽象方法run()方法
        while (isFlag){
            synchronized (this) {
                show();
            }
        }
    }
}

🍺输出结果(部分)

image.png

但是现在还是用的“同步代码块”来解决问题。


现在操作ticket的代码完全写在了show()方法里面,那么将这个show方法加一个同步即可,就是直接加一个synchronized,如下:

image.png

🌱代码

public class WindowTest2 {
    public static void main(String[] args) {
        //3.创建当前实现类的对象
        SaleTicket2 s=new SaleTicket2();

        //4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
        Thread t1 = new Thread(s);
        Thread t2 = new Thread(s);
        Thread t3 = new Thread(s);

        //给三个线程起名字
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        //5.通过Thread类的实例调用start():1.启动线程 2.调用当前线程的run()。
        t1.start();
        t2.start();
        t3.start();
    }
}

class SaleTicket2 implements Runnable{   //卖票    1.创建一个实现Runnable接口的类(实现类)
    int ticket=100;
    boolean isFlag=true;
    public synchronized void show(){ //此时的同步监视器就是:this 。此题目中是s,是唯一的,线程安全
        if(ticket>0){   //如果票数大于0就可以售票
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //哪个窗口卖票了,票卖了多少
            System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);  //最开始票号为100
            ticket--;
        }else{
            isFlag=false;
        }
    }
    @Override
    public void run() { //2.实现接口中的抽象方法run()方法
        while (isFlag){
            show();
        }
    }
}

🍺输出结果(部分)

image.png

可以。


2、案例1之同步监视器

上面的show()方法中,我们没有显示得去写同步监视器,其实它是默认的。

针对于这个同步方法,若这个方法是非静态的,那么这个同步监视器默认的就是this

image.png

这个this是改不了的,我们只能考虑这个this是不是唯一的。

🎲此时this是唯一的吗?

是唯一的。因为现在实在当前实现方式里面写的,类SaleTicket2的对象只造了一个,并且被多个线程所共用。所以调用方法的时候,只有唯一的对象s

如下:

image.png

所以线程是安全的,没有问题。

(2)同步方法–案例2

1、案例2之同步监视器的问题

还是拿这个例子来说,方式二继承Thread类,如下:

🌱代码

package yuyi02;

/**
 * ClassName: WindowTest3
 * Package: yuyi02
 * Description:
 *      使用同步方法解决继承Thread类的线程安全问题
 * @Author 雨翼轻尘
 * @Create 2024/1/30 0030 11:03
 */
public class WindowTest3 {
    public static void main(String[] args) {
        //3.创建3个窗口  创建当前Thread的子类的对象
        Window w1=new Window();
        Window w2=new Window();
        Window w3=new Window();

        //命名
        w1.setName("窗口1");
        w2.setName("窗口2");
        w3.setName("窗口3");

        //4.通过对象调用start(): 1.启动线程 2.调用当前线程的run()方法
        w1.start();
        w2.start();
        w3.start();
    }
}

class Window extends Thread{    //卖票  1.创建一个继承于Thread类的子类
    //票
    static int ticket=100;

    //2.重写Thread类的run() —>将此线程要执行的操作,声明在此方法体中
    @Override
    public void run() {
        while (true){
            if(ticket>0){   //如果票数大于0就可以售票
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //哪个窗口卖票了,票卖了多少
                System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);  //最开始票号为100
                ticket--;
            }else{
                break;
            }
        }
    }
}

🍺输出结果(部分)

image.png

出现了重票的问题。


现在来解决这个安全问题。

操作ticket的代码:

image.png

将上述操作ticket的代码放在方法show1()中,如下:

image.png

跟上一个案例类似,将break去掉,加一个isFlag1,如下:

image.png

当然,isFlag都要共用一个,所以需要加上static,如下:

image.png


🌱代码

public class WindowTest3 {
    public static void main(String[] args) {
        //3.创建3个窗口  创建当前Thread的子类的对象
        Window w1=new Window();
        Window w2=new Window();
        Window w3=new Window();

        //命名
        w1.setName("窗口1");
        w2.setName("窗口2");
        w3.setName("窗口3");

        //4.通过对象调用start(): 1.启动线程 2.调用当前线程的run()方法
        w1.start();
        w2.start();
        w3.start();
    }
}

class Window extends Thread{    //卖票  1.创建一个继承于Thread类的子类
    //票
    static int ticket=100;
    static boolean isFlag1=true;

    //2.重写Thread类的run() —>将此线程要执行的操作,声明在此方法体中
    @Override
    public void run() {
        while (isFlag1){
            show1();
        }
    }

    public void show1(){
        if(ticket>0){   //如果票数大于0就可以售票
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //哪个窗口卖票了,票卖了多少
            System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);  //最开始票号为100
            ticket--;
        }else{
            isFlag1=false;
        }
    }
}

🍺输出结果(部分)

现在还没有解决线程安全问题,所以输出结果还是有重票的,如下:

image.png


现在我们直接给show1()方法加上synchronized,可以吗?

如下:

image.png

🌱代码

public class WindowTest3 {
    public static void main(String[] args) {
        //3.创建3个窗口  创建当前Thread的子类的对象
        Window w1=new Window();
        Window w2=new Window();
        Window w3=new Window();

        //命名
        w1.setName("窗口1");
        w2.setName("窗口2");
        w3.setName("窗口3");

        //4.通过对象调用start(): 1.启动线程 2.调用当前线程的run()方法
        w1.start();
        w2.start();
        w3.start();
    }
}

class Window extends Thread{    //卖票  1.创建一个继承于Thread类的子类
    //票
    static int ticket=100;
    static boolean isFlag1=true;

    //2.重写Thread类的run() —>将此线程要执行的操作,声明在此方法体中
    @Override
    public void run() {
        while (isFlag1){
            show1();
        }
    }

    public synchronized void show1(){   //非静态同步方法,此时同步监视器就是this,此问题中的this有:w1,w2,w3
        if(ticket>0){   //如果票数大于0就可以售票
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //哪个窗口卖票了,票卖了多少
            System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);  //最开始票号为100
            ticket--;
        }else{
            isFlag1=false;
        }
    }
}

🍺输出结果(部分)

image.png

此时是非静态同步方法,同步监视器就是this,此问题中的this有:w1,w2,w3(当前类的对象造了三个)。所以肯定不行


2、案例2的补充说明

上面那个既然不行,那该怎么办呢?

show()方法改成静态的吗?如下:

image.png

🌱代码

public class WindowTest3 {
    public static void main(String[] args) {
        //3.创建3个窗口  创建当前Thread的子类的对象
        Window w1 = new Window();
        Window w2 = new Window();
        Window w3 = new Window();

        //命名
        w1.setName("窗口1");
        w2.setName("窗口2");
        w3.setName("窗口3");

        //4.通过对象调用start(): 1.启动线程 2.调用当前线程的run()方法
        w1.start();
        w2.start();
        w3.start();
    }
}

class Window extends Thread {    //卖票  1.创建一个继承于Thread类的子类
    //票
    static int ticket = 100;
    static boolean isFlag1 = true;

    //2.重写Thread类的run() —>将此线程要执行的操作,声明在此方法体中
    @Override
    public void run() {
        while (isFlag1) {
            show1();
        }
    }
    
    public static synchronized void show1() {   //静态方法的同步监视器是:当前类,就是Window.class
        if (ticket > 0) {   //如果票数大于0就可以售票
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //哪个窗口卖票了,票卖了多少
            System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);  //最开始票号为100
            ticket--;
        } else {
            isFlag1 = false;
        }
    }

}

🍺输出结果(部分)

image.png

现在这个案例加上static是可行的。

静态方法的同步监视器是当前类本身,就是Window.class(这里是一个对象,一个值,不是类),是唯一的。所以现在是安全的。

🍰说明

这个方法能不能改成静态的,需要看具体的问题。适合就可以改,不适合就不要改了。

若有的方法就是一个实例方法,里面要用实例变量,那就不适合改,同步方法就不靠谱了。

所以这里不要刻意去满足同步方法让它去达到我们的要求(不要为了线程安全,去特意将方法改为静态的)。

有的时候这个方法就不适合加上静态,同步方法就不适合去做了,就不要使用同步方法了。

那我们就主动将操作ticket的代码用synchronized包裹一下,然后指定一个同步监视器即可。

二、代码及重要说明

(1)代码

①【使用同步方法解决实现Runnable接口的线程安全问题】

🌱代码

package yuyi02;

/**
 * ClassName: WindowTset2
 * Package: yuyi02
 * Description:
 *      使用同步方法解决实现Runnable接口的线程安全问题
 * @Author 雨翼轻尘
 * @Create 2024/1/30 0030 9:52
 */
public class WindowTest2 {
    public static void main(String[] args) {
        //3.创建当前实现类的对象
        SaleTicket2 s=new SaleTicket2();

        //4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的实例
        Thread t1 = new Thread(s);
        Thread t2 = new Thread(s);
        Thread t3 = new Thread(s);

        //给三个线程起名字
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        //5.通过Thread类的实例调用start():1.启动线程 2.调用当前线程的run()。
        t1.start();
        t2.start();
        t3.start();
    }
}

class SaleTicket2 implements Runnable{   //卖票    1.创建一个实现Runnable接口的类(实现类)
    int ticket=100;
    boolean isFlag=true;

    public synchronized void show(){    //此时的同步监视器就是:this 。此题目中是s,是唯一的,线程安全
        if(ticket>0){   //如果票数大于0就可以售票
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //哪个窗口卖票了,票卖了多少
            System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);  //最开始票号为100
            ticket--;
        }else{
            isFlag=false;
        }
    }
    @Override
    public void run() { //2.实现接口中的抽象方法run()方法
        while (isFlag){
            show();
        }
    }
}

②【使用同步方法解决继承Thread类的线程安全问题】

🌱代码

package yuyi02;

/**
 * ClassName: WindowTest3
 * Package: yuyi02
 * Description:
 *      使用同步方法解决继承Thread类的线程安全问题
 * @Author 雨翼轻尘
 * @Create 2024/1/30 0030 11:03
 */
public class WindowTest3 {
    public static void main(String[] args) {
        //3.创建3个窗口  创建当前Thread的子类的对象
        Window w1 = new Window();
        Window w2 = new Window();
        Window w3 = new Window();

        //命名
        w1.setName("窗口1");
        w2.setName("窗口2");
        w3.setName("窗口3");

        //4.通过对象调用start(): 1.启动线程 2.调用当前线程的run()方法
        w1.start();
        w2.start();
        w3.start();
    }
}

class Window extends Thread {    //卖票  1.创建一个继承于Thread类的子类
    //票
    static int ticket = 100;
    static boolean isFlag1 = true;

    //2.重写Thread类的run() —>将此线程要执行的操作,声明在此方法体中
    @Override
    public void run() {
        while (isFlag1) {
            show1();
        }
    }

    public static synchronized void show1() {   //非静态同步方法,此时同步监视器就是this,此问题中的this有:w1,w2,w3,线程仍然不安全,加一个static
        if (ticket > 0) {   //如果票数大于0就可以售票
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //哪个窗口卖票了,票卖了多少
            System.out.println(Thread.currentThread().getName() + "售票,票号为:" + ticket);  //最开始票号为100
            ticket--;
        } else {
            isFlag1 = false;
        }
    }

}

(2)重要说明

【同步方法】

🗳️格式:

public synchronized void method(){
    可能会产生线程安全问题的代码
}

🚗说明

  • 如果操作共享数据的代码(需要被同步的代码)完整的声明在了一个方法中,那么我们就可以将此方法声明为同步方法即可。
  • 非静态的同步方法,默认同步监视器是this静态的同步方法,默认同步监视器是当前类本身

☕注意

现在咱们线程一共说了这么几件事情,如下:

image.png

下面来看一下这个关键字:synchronized(同步的)

  • 好处:解决了线程的安全问题
  • 弊端:在操作共享数据时,多线程其实是串行执行的,意味着性能低

卖票:三个线程来做,交互去执行。

当一个线程还没有操作完,其他线程也过来了,就会出现安全问题。

执行前面代码的时候,三个线程没有共享数据,同时执行也没有问题。

但是在执行共享数据的代码的时候,只能让一个线程进去,其他线程在外面等着。

也就是说,执行前面代码的时候,三个线程可以并发执行,但是在操作共享数据的时候,一定是串行的去执行,也就是只有一个线程可以进去执行。所以性能会差一点

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/359472.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云计算HCIE备考经验分享

大家好,我是来自深圳信息职业技术学院22级鲲鹏3-1班的刘同学,在2023年9月19日成功通过了华为云计算HCIE认证,并且取得了A的成绩。下面把我的考证经验分享给大家。 转专业进鲲鹏班考HCIE 大一上学期的时候,在上Linux课程的时候&…

代码随想录 Leetcode222.完全二叉树的节点个数

题目&#xff1a; 代码&#xff08;首刷自解 2024年1月30日&#xff09;&#xff1a; class Solution { public:int countNodes(TreeNode* root) {int res 0;if (root nullptr) return res;queue<TreeNode*> deque;TreeNode* cur root;deque.push(cur);int size 0;w…

注册亚马逊店铺用动态IP可以吗?

注册亚马逊店铺可以用动态IP&#xff0c;只要是独立且干净的网线就没问题&#xff0c;亚马逊规则要求一个IP地址只能出现一个亚马逊店铺&#xff0c;若使用不当会导致关联账户。 固定ip可以给我们的账户带来更多的安全&#xff0c;要知道关联问题是亚马逊上的一个大问题&#…

DBCO-PEG8-Amine,二苯并环辛炔 PEG8 氨基,具有良好反应活性

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;二苯并环辛炔-八聚乙二醇-氨基&#xff0c;二苯并环辛炔 PEG8 氨基&#xff0c;DBCO-PEG8-NH2&#xff0c;DBCO-PEG8-Amine 一、基本信息 产品简介&#xff1a;DBCO-PEG8-NH2 is a compound with good reactivity. …

ubuntu20.04安装sumo

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 有问题&#xff0c;请大家指出&#xff0c;争取使方法更完善。这只是ubuntu安装sumo的一种方法。一、注意事项1、首先明确你的ubuntu的用户名是什么 二、sumo安装1.…

Python爬虫实践指南:利用cpr库爬取技巧

引言 在信息时代&#xff0c;数据是无价之宝。为了获取网络上的丰富数据&#xff0c;网络爬虫成为了不可或缺的工具。在Python这个强大的编程语言中&#xff0c;cpr库崭露头角&#xff0c;为网络爬虫提供了便捷而高效的解决方案。本文将深入探讨如何利用cpr库实现数据爬取的各…

Ruff应用:打破传统,IoT技术赋能工业制造数字化转型之路

近年来&#xff0c;随着物联网、大数据、云计算、5G等数字技术的快速应用&#xff0c;工业制造领域正在经历着前所未有的变革。工业4.0时代&#xff0c;各种数字技术与工业制造的结合&#xff0c;不仅提高了工业生产效率、降低运营成本&#xff0c;更是极大地推动了传统工业数字…

智能小程序事件系统——SJS响应事件实现方案

背景信息 如有频繁用户交互&#xff0c;在小程序上表现是比较卡顿的。例如&#xff0c;页面有 2 个元素 A 和 B&#xff0c;用户在 A 上做 touchmove 手势&#xff0c;要求 B 也跟随移动&#xff0c;movable-view 就是一个典型的例子。一次 touchmove 事件的响应过程为&#x…

GPT-4 Vision调试任何应用,即使缺少文本日志 升级Streamlit七

GPT-4 Vision 系列: 翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式二翻译: GPT-4 Vision静态图表转换为动态数据可视化 升级Streamlit 三翻译: GPT-4 Vision从图像转换为完全可编辑的表格 升级St…

springboot 个人网盘系统 java web网盘文件分享系统 web在线云盘

springboot 个人网盘系统 java web网盘文件分享系统 web在线云盘 开发工具&#xff1a;Eclipse/idea Java开发环境&#xff1a;JDK8.0 Web服务器:Tomcate9.0。 数据库&#xff1a;MySQL数据库。 技术框架&#xff1a;Struts2SpringHibernate和JSP 有详细的源码&#xff0…

人脸识别技术在网络安全中有哪些应用前景?

人脸识别技术在网络安全中有广泛的应用前景。以下是一些主要的应用方向&#xff1a; 1. 身份验证和访问控制&#xff1a;人脸识别可以用作一种更安全和方便的身份验证方法。通过将用户的人脸与事先注册的人脸进行比对&#xff0c;可以实现强大的身份验证&#xff0c;避免了传统…

自动驾驶:Apollo如何塑造人类的未来出行

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言1. 什么是自定义指令&#xff1f;2. Apollo中的自定义指令2.1 查询中的自定…

开源博客项目Blog .NET Core源码学习(8:EasyCaching使用浅析)

开源博客项目Blog使用EasyCaching模块实现缓存功能&#xff0c;主要是在App.Framwork项目中引用了多类包&#xff0c;包括内存缓存&#xff08;EasyCaching.InMemory&#xff09;、Redis缓存&#xff08;EasyCaching.CSRedis&#xff09;&#xff0c;同时支持多种序列化方式&am…

微软Office Plus与WPS Office的较量:办公软件市场将迎来巨变?

微软Office Plus在功能表现上远超WPS Office&#xff1f; 微软出品的Office套件实力强劲&#xff0c;其不仅在办公场景中扮演着不可或缺的角色&#xff0c;为用户带来高效便捷的体验&#xff0c;而且在娱乐生活管理等多元领域中同样展现出了卓越的应用价值 作为中国本土办公软…

GPT-4 Vision根据应用程序截图生成博客和Readme 升级Streamlit八

GPT-4 Vision 系列: 翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式二翻译: GPT-4 Vision静态图表转换为动态数据可视化 升级Streamlit 三翻译: GPT-4 Vision从图像转换为完全可编辑的表格 升级St…

回归预测 | Matlab实现CPO-BiLSTM【24年新算法】冠豪猪优化双向长短期记忆神经网络多变量回归预测

回归预测 | Matlab实现CPO-BiLSTM【24年新算法】冠豪猪优化双向长短期记忆神经网络多变量回归预测 目录 回归预测 | Matlab实现CPO-BiLSTM【24年新算法】冠豪猪优化双向长短期记忆神经网络多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-B…

python中的josn方法相关介绍

如果需要在不同的编程语言之间传递对象&#xff0c;就必须把对象序列化为标准格式&#xff0c;比如XML&#xff0c;但更好的方法是序列化为JSON&#xff0c;因为JSON表示出来就是一个字符串&#xff0c;可以被所有语言读取&#xff0c;也可以方便地存储到磁盘或者通过网络传输。…

maven helper 解决jar包冲突方法

一 概要说明 1.1 说明 首先&#xff0c;解决idea中jar包冲突&#xff0c;使用maven的插件&#xff1a;maven helper插件&#xff0c;它能够给我们罗列出来同一个jar包的不同版本&#xff0c;以及他们的来源&#xff0c;但是对不同jar包中同名的类没有办法。 1.2 依赖顺序 …

[嵌入式系统-6]:龙芯1B 开发学习套件 -3-软件层次架构

目录 一、龙芯软件架构 1.1 通用软件架构 1.2 龙芯软件架构 1.3 龙芯各种应用程序 1.4 龙芯SOC芯片硬件&#xff1a;龙芯1B 1.5 PMON软件 1.6 龙芯IDE管辖的软件 &#xff08;1&#xff09;CPU Core驱动程序 &#xff08;2&#xff09;SOC芯片外设驱动程序 &#xff…

LeetCode.2808. 使循环数组所有元素相等的最少秒数

题目 题目链接 分析 我们最终形成的数组一定是当前数组nums 中的一个数字。 所以我们的想法就是枚举数组 nums 中的所有数字&#xff0c;取最小值。 题目告诉我们每一秒都可以向左右扩散一位&#xff0c;那么多个相同的 x 同时扩散&#xff0c;扩散完整个数组耗时就取决于两…