【java学习—十五】线程的同步与死锁(5)

文章目录

  • 1. 多线程产生的问题
  • 2. Synchronized 的使用方法
  • 3. 线程的死锁问题


1. 多线程产生的问题

问题:
同一个账户,支付宝转账,微信转账。两个手机,一个手机开支付宝,另一个手机开微信。假设账户上有3000元,支付宝和微信同时提款2000,这时你的账户余额会变成了-1000元吗?
答:
当然不会,出现就有问题了
    
多个线程执行的不确定性引起执行结果的不稳定
多个线程对账本的共享,会造成操作的不完整性,会破坏数据。

代码实现:

package day15;

public class Test2 {
	public static void main(String[] args) {
		
		//定义账户对象
		Account a = new Account();
		
		//多线程对象
		User u_weixin = new User(a, 2000);
		User u_zhifubao = new User(a, 2000);
		
		Thread weixin = new Thread(u_weixin, "微信");
		Thread zhifubao = new Thread(u_zhifubao, "支付宝");
		
		weixin.start();
		zhifubao.start();
		
	}

}

class Account{
	public static int money = 3000;//全局变量,所有操作共享这个变量
	
	/**
	 * 提款先判断账户钱够不够
	 * 多线程调用这个方法就有问题,线程共享资源时,一个线程在执行这个方法没有完毕时,另一个线程又开始执行这个方法
	 * 解决思路:先让一个线程整体执行完这个方法,另一个线程再执行。
	 * @param m
	 */
	public void drawing(int m) {
		String name = Thread.currentThread().getName();
		
		if(money < m) {
			System.out.println(name + "操作,账户金额不足:" + money);
		}else {
			System.out.println(name + "操作,账户原有金额:" + money);
			System.out.println(name + "操作,取款金额:" + m);
			
			money = money - m;
			
			System.out.println(name + "操作,取款后的余额:" + money);
		}
		
	}
}

class User implements Runnable{
	
	Account account;
	int money;
	
	public User(Account account, int money) {
		this.account = account;
		this.money = money;
	}
	
	@Override
	public void run() {
		account.drawing(money);
		
	}
}

运行结果:

在这里插入图片描述

发现金额变成 -1000 了

    

多线程出现了安全问题

问题的原因
    当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。

解决办法 :
    对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。

2. Synchronized 的使用方法

Java 对于多线程的安全问题提供了专业的解决方式:

同步机制

1 、 synchronized 还可以放在方法声明中,表示整个方法为同步方法。
如果针对对象要加同步锁,那就加在方法上,例如:
    public synchronized void show (String name){
        ....
    }

2 、 锁 代码块

如果针对某一段代码需要加同步锁,那就直接在代码块上加同步锁,例如:
    synchronized ( 对象) {
        // 需要被同步的代码;
    }


解决方法:
直接在方法上加上synchronized关键字

package day15;

public class Test2 {
	public static void main(String[] args) {
		
		//定义账户对象
		Account a = new Account();
		
		//多线程对象
		User u_weixin = new User(a, 2000);
		User u_zhifubao = new User(a, 2000);
		
		Thread weixin = new Thread(u_weixin, "微信");
		Thread zhifubao = new Thread(u_zhifubao, "支付宝");
		
		weixin.start();
		zhifubao.start();
		
	}
}

class Account{
	public static int money = 3000;//全局变量,所有操作共享这个变量
	
	/**
	 * 提款先判断账户钱够不够
	 * 多线程调用这个方法就有问题,线程共享资源时,一个线程在执行这个方法没有完毕时,另一个线程又开始执行这个方法
	 * 解决思路:先让一个线程整体执行完这个方法,另一个线程再执行。
	 * 通过 synchronized同步锁 来完成
	 * 可以直接在方法上加上synchronized关键字
	 * 在普通方法上加同步锁synchronized,锁的是整个对象,不是某一个方法
	 * @param m
	 */
	public synchronized void drawing(int m) {
		String name = Thread.currentThread().getName();
		
		if(money < m) {
			System.out.println(name + "操作,账户金额不足:" + money);
		}else {
			System.out.println(name + "操作,账户原有金额:" + money);
			System.out.println(name + "操作,取款金额:" + m);
			
			money = money - m;
			
			System.out.println(name + "操作,取款后的余额:" + money);
		}
	}
		
}

class User implements Runnable{
	
	Account account;
	int money;
	
	public User(Account account, int money) {
		this.account = account;
		this.money = money;
	}
	
	@Override
	public void run() {
		account.drawing(money);
		
	}
}

运行结果:

在这里插入图片描述


在普通方法上加同步锁synchronized,锁的是整个对象,不是某一个方法

举例:

package day15;

public class Test2 {
	public static void main(String[] args) {
		
		//定义账户对象
		Account a = new Account();
		
		//多线程对象
		User u_weixin = new User(a, 2000);
		User u_zhifubao = new User(a, 2000);
		
		Thread weixin = new Thread(u_weixin, "微信");
		Thread zhifubao = new Thread(u_zhifubao, "支付宝");
		
		weixin.start();
		zhifubao.start();
		
		
	}

}

class Account{
	public static int money = 3000;//全局变量,所有操作共享这个变量
	
	/**
	 * 提款先判断账户钱够不够
	 * 多线程调用这个方法就有问题,线程共享资源时,一个线程在执行这个方法没有完毕时,另一个线程又开始执行这个方法
	 * 解决思路:先让一个线程整体执行完这个方法,另一个线程再执行。
	 * 通过 synchronized同步锁 来完成
	 * 可以直接在方法上加上synchronized关键字
	 * 在普通方法上加同步锁synchronized,锁的是整个对象,不是某一个方法
	 * 
	 * 普通方法加同步锁,锁的是当前方法对应的对象,当前的对象的所有加了同步锁的方法是共用一个同步锁
	 * @param m
	 */
	public synchronized void drawing(int m) {
		String name = Thread.currentThread().getName();
		
		if(money < m) {
			System.out.println(name + "操作,账户金额不足:" + money);
		}else {
			System.out.println(name + "操作,账户原有金额:" + money);
			System.out.println(name + "操作,取款金额:" + m);
			
			money = money - m;
			
			System.out.println(name + "操作,取款后的余额:" + money);
		}
		
	}
	
	public synchronized void drawing1(int m) {
		String name = Thread.currentThread().getName();
		
		if(money < m) {
			System.out.println(name + "操作,账户金额不足:" + money);
		}else {
			System.out.println(name + "操作,账户原有金额:" + money);
			System.out.println(name + "操作,取款金额:" + m);
			
			money = money - m;
			
			System.out.println(name + "操作,取款后的余额:" + money);
		}
		
	}
	
	
}

class User implements Runnable{
	
	Account account;
	int money;
	
	public User(Account account, int money) {
		this.account = account;
		this.money = money;
	}
	
	@Override
	public void run() {

		if(Thread.currentThread().getName().equals("微信")) {
			account.drawing(money);
		}else {
			account.drawing1(money);
		}
		
	}
}

运行结果:

在这里插入图片描述

运行结果和上一段相同
说明:锁死的是 Account a 这个对象

普通方法加同步锁,锁的是当前方法对应的对象,当前的对象的所有加了同步锁的方法是共用一个同步锁


不同的对象是不同的锁

举例:

package day15;

public class Test2 {
	public static void main(String[] args) {
		
		//定义账户对象
		Account a = new Account();
		Account a1 = new Account();
		
		//多线程对象
		User u_weixin = new User(a, 2000);
		User u_zhifubao = new User(a1, 2000);
		
		Thread weixin = new Thread(u_weixin, "微信");
		Thread zhifubao = new Thread(u_zhifubao, "支付宝");
		
		weixin.start();
		zhifubao.start();
		
		
	}

}

class Account{
	public static int money = 3000;//全局变量,所有操作共享这个变量
	
	/**
	 * 提款先判断账户钱够不够
	 * 多线程调用这个方法就有问题,线程共享资源时,一个线程在执行这个方法没有完毕时,另一个线程又开始执行这个方法
	 * 解决思路:先让一个线程整体执行完这个方法,另一个线程再执行。
	 * 通过 synchronized同步锁 来完成
	 * 可以直接在方法上加上synchronized关键字
	 * 在普通方法上加同步锁synchronized,锁的是整个对象,不是某一个方法,
	 * 不同的对象是不同的锁,普通方法中加synchronized,线程使用不同的此方法的对象,还是有资源共享的问题
	 * @param m
	 */
	public synchronized void drawing(int m) {
		String name = Thread.currentThread().getName();
		
		if(money < m) {
			System.out.println(name + "操作,账户金额不足:" + money);
		}else {
			System.out.println(name + "操作,账户原有金额:" + money);
			System.out.println(name + "操作,取款金额:" + m);
			
			money = money - m;
			
			System.out.println(name + "操作,取款后的余额:" + money);
		}
		
	}
	
	public synchronized void drawing1(int m) {
		String name = Thread.currentThread().getName();
		
		if(money < m) {
			System.out.println(name + "操作,账户金额不足:" + money);
		}else {
			System.out.println(name + "操作,账户原有金额:" + money);
			System.out.println(name + "操作,取款金额:" + m);
			
			money = money - m;
			
			System.out.println(name + "操作,取款后的余额:" + money);
		}
		
	}
	
	
}

class User implements Runnable{
	
	Account account;
	int money;
	
	public User(Account account, int money) {
		this.account = account;
		this.money = money;
	}
	
	@Override
	public void run() {
	
		if(Thread.currentThread().getName().equals("微信")) {
			account.drawing(money);
		}else {
			account.drawing1(money);
		}
		
	}
}

运行结果:

在这里插入图片描述


如何解决上述问题:

举例:

package day15;

public class Test2 {
	public static void main(String[] args) {
		
		//定义账户对象
		Account a = new Account();
		Account a1 = new Account();
		
		//多线程对象
		User u_weixin = new User(a, 2000);
		User u_zhifubao = new User(a1, 2000);
		
		Thread weixin = new Thread(u_weixin, "微信");
		Thread zhifubao = new Thread(u_zhifubao, "支付宝");
		
		weixin.start();
		zhifubao.start();
		
		
	}

}

class Account{
	public static int money = 3000;//全局变量,所有操作共享这个变量	
	
	/**
	 * 静态方法 + synchronized,对于所有的对象都是使用同一个锁
	 * @param m
	 */
	public static synchronized void drawing2(int m) {
		String name = Thread.currentThread().getName();
		
		if(money < m) {
			System.out.println(name + "操作,账户金额不足:" + money);
		}else {
			System.out.println(name + "操作,账户原有金额:" + money);
			System.out.println(name + "操作,取款金额:" + m);
			
			money = money - m;
			
			System.out.println(name + "操作,取款后的余额:" + money);
		}
		
	}
}

class User implements Runnable{
	
	Account account;
	int money;
	
	public User(Account account, int money) {
		this.account = account;
		this.money = money;
	}
	
	@Override
	public void run() {

		account.drawing2(money);//调用类的静态方法
	}
}

运行结果:

在这里插入图片描述


锁代码块

举例:

package day15;

public class Test2 {
	public static void main(String[] args) {
		
		//定义账户对象
		Account a = new Account();
		Account a1 = new Account();
		
		//多线程对象
		User u_weixin = new User(a, 2000);
		User u_zhifubao = new User(a, 2000);
		
		Thread weixin = new Thread(u_weixin, "微信");
		Thread zhifubao = new Thread(u_zhifubao, "支付宝");
		
		weixin.start();
		zhifubao.start();	
		
	}
}

class Account{
	public static int money = 3000;//全局变量,所有操作共享这个变量
				
	/**
	 * 对代码块加入同步锁
	 * 代码块synchronized(this),所有当前的对象的synchronized(this)同步的代码都是使用同一个锁
	 * @param m
	 */
	public void drawing3(int m) {
		
		synchronized(this) {//表示当前对象的代码块被加了synchronized同步锁
			//用this锁代码块是代表当前的对象,如果在其他的方法中也有synchronized(this)的代码块,使用的都是同一个同步锁
			String name = Thread.currentThread().getName();
			
			if(money < m) {
				System.out.println(name + "操作,账户金额不足:" + money);
			}else {
				System.out.println(name + "操作,账户原有金额:" + money);
				System.out.println(name + "操作,取款金额:" + m);
				
				money = money - m;
				
				System.out.println(name + "操作,取款后的余额:" + money);
			}
		}
	}
	
}

class User implements Runnable{
	
	Account account;
	int money;
	
	public User(Account account, int money) {
		this.account = account;
		this.money = money;
	}
	
	@Override
	public void run() {

		account.drawing3(money);
	}
}

运行结果:

在这里插入图片描述


如果在其他的方法中也有synchronized(this)的代码块,使用的都是同一个同步锁

举例:

package day15;

public class Test2 {
	public static void main(String[] args) {
		
		//定义账户对象
		Account a = new Account();
		
		//多线程对象
		User u_weixin = new User(a, 2000);
		User u_zhifubao = new User(a, 2000);
		
		Thread weixin = new Thread(u_weixin, "微信");
		Thread zhifubao = new Thread(u_zhifubao, "支付宝");
		
		weixin.start();
		zhifubao.start();
	}
}

class Account{
	public static int money = 3000;//全局变量,所有操作共享这个变量
	
	/**
	 * 对代码块加入同步锁
	 * @param m
	 */
	public void drawing3(int m) {
		
		synchronized(this) {//表示当前对象的代码块被加了synchronized同步锁
			//用this锁代码块是代表当前的对象,如果在其他的方法中也有synchronized(this)的代码块,使用的都是同一个同步锁
			String name = Thread.currentThread().getName();
			
			if(money < m) {
				System.out.println(name + "操作,账户金额不足:" + money);
			}else {
				System.out.println(name + "操作,账户原有金额:" + money);
				System.out.println(name + "操作,取款金额:" + m);
				
				money = money - m;
				
				System.out.println(name + "操作,取款后的余额:" + money);
			}
		}
	}
	
	
	public void drawing4(int m) {
		
		synchronized(this) {//表示当前对象的代码块被加了synchronized同步锁
			//用this锁代码块是代表当前的对象,如果在其他的方法中也有synchronized(this)的代码块,使用的都是同一个同步锁
			String name = Thread.currentThread().getName();
			
			if(money < m) {
				System.out.println(name + "操作,账户金额不足:" + money);
			}else {
				System.out.println(name + "操作,账户原有金额:" + money);
				System.out.println(name + "操作,取款金额:" + m);
				
				money = money - m;
				
				System.out.println(name + "操作,取款后的余额:" + money);
			}
		}
	}

}

class User implements Runnable{
	
	Account account;
	int money;
	
	public User(Account account, int money) {
		this.account = account;
		this.money = money;
	}
	
	@Override
	public void run() {

		if(Thread.currentThread().getName().equals("微信")) {
			account.drawing3(money);
		}else {
			account.drawing4(money);
		}
		
		
	}
}

运行结果:

在这里插入图片描述


怎么使用不同的同步锁

举例:
(1)锁同一个对象,设置a、a1两个账户

package day15;

public class Test2 {
	public static void main(String[] args) {
		
		//定义账户对象
		Account a = new Account();
		Account a1 = new Account();
		
		//多线程对象
		User u_weixin = new User(a, 2000);
		User u_zhifubao = new User(a1, 2000);
		
		Thread weixin = new Thread(u_weixin, "微信");
		Thread zhifubao = new Thread(u_zhifubao, "支付宝");
		
		weixin.start();
		zhifubao.start();
		
		
	}

}

class Account{
	public static int money = 3000;//全局变量,所有操作共享这个变量
	
	/**
	 * synchronized修饰代码块,想要根据不同的对象有不同的锁
	 * @param m
	 */
	public void drawing5(int m, Account a) {
		
		synchronized(a) {//表示通过方法的参数传递进来的对象的代码块被加了synchronized同步锁
			//不同的对象就有不同的同步锁
			String name = Thread.currentThread().getName();
			
			if(money < m) {
				System.out.println(name + "操作,账户金额不足:" + money);
			}else {
				System.out.println(name + "操作,账户原有金额:" + money);
				System.out.println(name + "操作,取款金额:" + m);
				
				money = money - m;
				
				System.out.println(name + "操作,取款后的余额:" + money);
			}
		}
	}
	
}

class User implements Runnable{
	
	Account account;
	int money;
	
	public User(Account account, int money) {
		this.account = account;
		this.money = money;
	}
	
	@Override
	public void run() {
		
		account.drawing5(money, account);	
	}
}

运行结果:

在这里插入图片描述


(2)锁同一个对象,只设置a一个账户

package day15;

public class Test2 {
	public static void main(String[] args) {
		
		//定义账户对象
		Account a = new Account();
		
		//多线程对象
		User u_weixin = new User(a, 2000);
		User u_zhifubao = new User(a, 2000);
		
		Thread weixin = new Thread(u_weixin, "微信");
		Thread zhifubao = new Thread(u_zhifubao, "支付宝");
		
		weixin.start();
		zhifubao.start();
		
	}
}

class Account{
	public static int money = 3000;//全局变量,所有操作共享这个变量

	/**
	 * synchronized修饰代码块,想要根据不同的对象有不同的锁
	 * synchronized(a)这个小括号中传入不同的对象就是不同的锁
	 * @param m
	 */
	public void drawing5(int m, Account a) {
		
		synchronized(a) {//表示通过方法的参数传递进来的对象的代码块被加了synchronized同步锁
			//不同的对象就有不同的同步锁
			String name = Thread.currentThread().getName();
			
			if(money < m) {
				System.out.println(name + "操作,账户金额不足:" + money);
			}else {
				System.out.println(name + "操作,账户原有金额:" + money);
				System.out.println(name + "操作,取款金额:" + m);
				
				money = money - m;
				
				System.out.println(name + "操作,取款后的余额:" + money);
			}
		}
	}
	
	
	
}

class User implements Runnable{
	
	Account account;
	int money;
	
	public User(Account account, int money) {
		this.account = account;
		this.money = money;
	}
	
	@Override
	public void run() {
		
		account.drawing5(money, account);
	}
}

运行结果:

在这里插入图片描述

3. 线程的死锁问题

问题情景:
    线程a0,需要执行方法f0
    线程a1,需要执行方法f1
    f0和f1都是有同步锁的方法
    a0调用f1方法并且一直没有执行完f1
    a1调用f0方法并且一直没有执行完f0
    
导致a0和a1线程都在等待对方释放方法,对方都不释放,这样就形成了线程的死锁

死锁
    不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁

解决方法
    ①专门的算法、原则,比如加锁顺序一致
    ②尽量减少同步资源的定义,尽量避免锁未释放的场景

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

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

相关文章

OCC教学:拓扑

拓扑&#xff1a;1.介绍 几何限制 OCCT 曲面支持矩形修剪。布尔运算后可能会出现非矩形域。 如何存储剪切操作的结果&#xff1f; 拓扑的目的 一般来说&#xff0c;拓扑是描述对象局限性的一种手段。 OCC拓扑被用于用于描述&#xff1a; 物体的边界&#xff1b;对象之…

Mars3d-vue最简项目模板集成使用Mars3d的UI控件样板

备注说明&#xff1a; 1.小白可看步骤一二&#xff0c;进阶小白可直接看步骤三 步骤一&#xff1a;新建文件夹<uitest>&#xff0c;在mars3d仓库拉一份最简项目模板&#xff1a; git clone mars3d-vue-template: Vue3.x 技术栈下的Mars3D项目模板 步骤二&#xff1a;运…

01_SHELL编程之变量定义(一)

SHELL编程 该课程主要包括以下内容&#xff1a; ① Shell的基本语法结构 如&#xff1a;变量定义、条件判断、循环语句(for、until、while)、分支语句、函数和数组等&#xff1b; ② 基本正则表达式的运用&#xff1b; ③ 文件处理三剑客&#xff1a;grep、sed、awk工具的使用&…

最好用的Python库推荐总结,每一个都用处很大!

文章目录 分词 - jieba词云库 - wordcloud可视化进度条 - tpdm优美的表格 - PrettyTable多进程 - multiprocessing多线程 - threading谷歌翻译 - googletrans重复回调 - retrying游戏开发 - pygame绘图教程 - turtle数据分析 - pandas算法加密 - pycryto操作 win 电脑 - pywin3…

2—10岁女童羽绒服,黑色长款也太好看了吧

冬天怎么能没有一件暖呼呼的羽绒服呢&#xff1f; 黑色长款羽绒服也赞了吧 大长款连帽&#xff0c;防风保暖设计 时尚与美观度都兼具呢&#xff01;好穿又耐穿&#xff01;

qt定时器的使用

在QWidget中进行声明

大数据毕业设计之前端01:我的前端之路

初遇前端 初次接触前端还是2016年&#xff0c;那一年暑假心血来潮&#xff0c;在网易云课堂上学着前端三剑客&#xff08;html、js、css&#xff09;。18年毕业&#xff0c;把用各色水笔手写的花花绿绿笔记寄回家里&#xff0c;投身奔赴后端与大数据开发的征程。 遥记18年的毕…

关于hadoop报错ERROR: Cannot set priority of namenode process与jps仅有自身的某类解决办法

运行start-sh.all发现了如图的问题 也是搞了很久搜了很多教程&#xff0c;发现很多人并不是大毛病而是很多小细节出了错误。 首先检查如下hadoop-env.sh &#xff0c;core-site.xml &#xff0c;hdfs-site.xml &#xff0c;mapred-site.xml &#xff0c;yarn-site.xml 内容是…

flutter 绘制右上角圆角三角形标签

绘制&#xff1a; import package:jade/utils/JadeColors.dart; import package:flutter/material.dart; import dart:math as math;class LabelTopRightYellow extends StatefulWidget {final String labelTitle; // 只能两个字的&#xff08;文字偏移量没有根据文字长度改变…

要在伦敦银技术分析史上留名 这可能吗?

在学习伦敦银投资的时候&#xff0c;我们都很羡慕那些以人的名字命名的交易工具或者策略&#xff0c;例如布林带、帝纳波利点位、加特利形态、艾略特波浪理论等等。投资者也有一个希望&#xff0c;就是开发属于自己的交易策略或者工具&#xff0c;这并不是不可能的&#xff0c;…

C 语言指针和数组

C 语言指针和数组 在本教程中&#xff0c;您将了解C语言编程中数组与指针之间的关系。您还将学习使用指针访问数组元素。 在了解数组与指针之间的关系之前&#xff0c;请确保检查以下两个主体&#xff1a; [C 数组](C 语言数组-CSDN博客)[C 指针](C 语言指针-CSDN博客) 数组…

springboot327基于Java的医院急诊系统

交流学习&#xff1a; 更多项目&#xff1a; 全网最全的Java成品项目列表 https://docs.qq.com/doc/DUXdsVlhIdVlsemdX 演示 项目功能演示&#xff1a; ————————————————

解决编译时提示“没有那个文件或目录 #include <pcap.h>”的问题

解决编译时提示“没有那个文件或目录 #include 当你在编译代码时遇到“没有那个文件或目录 #include <pcap.h>”的错误提示&#xff0c;这通常意味着编译器在你的系统路径中找不到 pcap.h 头文件。pcap.h 是网络流量捕获库 pcap 的头文件&#xff0c;用于在 C/C 程序中捕…

高效能人士的七个习惯

今天小编给大家推荐最近读的一本书&#xff0c;史蒂芬柯维的《高效能人士的七个习惯》&#xff0c;分别是积极主动、以始为终、要事第一、双赢思维、知己解彼、综合高效及不断更新。 一、个人领域&#xff1a;从依赖到独立 习惯一&#xff1a;积极主动——个人愿景的原则付诸行…

哪种猫罐头比较好?推荐给新手养猫的5款好口碑猫罐头!

新手养猫很容易陷入疯狂购买的模式&#xff0c;但有些品牌真的不能乱买&#xff01;现在的大环境不太好&#xff0c;我们需要学会控制自己的消费欲望&#xff0c;把钱花在刀刃上&#xff01;哪种猫罐头比较好&#xff1f;现在宠物市场真的很内卷&#xff0c;很多品牌都在比拼产…

雷达模糊函数及MATLAB仿真

文章目录 前言一、雷达模糊函数二、Matlab 仿真1、单脉冲模糊函数①、MATLAB 源码②、仿真结果1&#xff09;不确定函数三维图2&#xff09;不确定函数的等高图3&#xff09;模糊函数的三维图4&#xff09;模糊函数的等高图 2、单脉冲多普勒频率轴上的切面①、MATLAB 源码②、仿…

nvm安装详细教程(卸载旧的nodejs,安装nvm、node、npm、cnpm、yarn及环境变量配置)

文章目录 一、完全卸载旧的nodejs1、打开系统的控制面板&#xff0c;点击卸载程序&#xff0c;卸载nodejs&#xff08;1&#xff09;打开系统的控制面板&#xff0c;点击程序下的卸载程序&#xff08;2&#xff09;找到node.js&#xff0c;鼠标右击出现下拉框&#xff0c;点卸载…

11月编程语言排行榜出炉:C#超越Java已成定局!

TIOBE最新的编程语言排行榜刚刚出炉了&#xff0c;本月Java依然大幅下跌3.63%&#xff0c;C#本月上涨3.4%&#xff0c;C#和Java仅相差0.7%。 就像网友评论说的&#xff1a;Java成于互联网的兴起&#xff0c;败于互联网的衰落。 一直以来我也都是从事互联网行业、主要是电商行业…

redis高级案列case

案列一 双写一致性 案例二 双锁策略 package com.redis.redis01.service;import com.redis.redis01.bean.RedisBs; import com.redis.redis01.mapper.RedisBsMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; imp…

comfyui指北-1

https://colab.research.google.com/github/tieai/SDXL-ComfyUI-Colab/blob/main/SDXL_OneClick_ComfyUI.ipynb#scrollToSaAJk33ppFw1https://colab.research.google.com/github/tieai/SDXL-ComfyUI-Colab/blob/main/SDXL_OneClick_ComfyUI.ipynb#scrollToSaAJk33ppFw1 可以用上…