Java实例——线程
1、查看线程存活状态
Thread.isAlive()
Thread.getName()
public class MyThread extends Thread{@Overridepublic void run() {for (int i = 0; i < 10; i++) {printMsg();}}public static void printMsg(){Thread thread = Thread.currentThread();//Thread.getName() 获取线程名称System.out.println("name=["+thread.getName()+"]");}public static void main(String[] args) {MyThread myThread = new MyThread();myThread.setName("MyThread"); //修改线程名称System.out.println("before start(),the Thread Alive = " + myThread.isAlive());//判断线程存活状态myThread.start();System.out.println("just after start(),the Thread Alive = " + myThread.isAlive());for (int i = 0; i < 10; i++) {printMsg();}System.out.println("the end of Thread Alive = " + myThread.isAlive());}
}
输出结果
before start(),the Thread Alive = false
just after start(),the Thread Alive = true
name=[main]
name=[main]
name=[main]
name=[main]
name=[MyThread]
name=[main]
name=[main]
name=[main]
name=[main]
name=[main]
name=[main]
name=[MyThread]
the end of Thread Alive = true
name=[MyThread]
name=[MyThread]
name=[MyThread]
name=[MyThread]
name=[MyThread]
name=[MyThread]
name=[MyThread]
name=[MyThread]
2、多线程同步锁
有三种同步锁:synchronize锁,lock锁,volatile锁
- synchronize锁是一般情况下Java多线程开发所使用的最常用同步锁。
- lock锁同样是常见同步锁。
- volatile锁是一种轻量同步锁,能够减轻同步锁所带来的的资源消耗,但只能所用在变量上。
lock锁与synchronize锁的区别:
- 两者都是可重入锁,自己可以再次获取自己的内部锁。
- synchronized是依赖于虚拟机的,而Lock锁依赖JDK。
- synchronized锁可以自动释放锁,而Lock锁必须要手动释放锁。
- synchronized锁的两个线程1和线程2,如果当前线程1获得锁,线程2等待,如果线程1阻塞,线程2会一致等待下去,而Lock锁不一定会等下去,如果尝试获几次取不到锁,线程2可以不用一直等待就结束了。
synchronize锁的使用场景:卖票
class MyThread extends Thread{public static void main(String[] args) {Ticket ticket=new Ticket();Thread thread = new Thread(ticket,"售票员小张");thread.start();Thread thread1 = new Thread(ticket,"售票员小刘");thread1.start();}
}
//票务系统
class Ticket implements Runnable {//总票数private int ticketCount = 40;@Overridepublic void run() {while (true) {//对票务类进行同步锁,避免线程产生脏数据synchronized (Ticket.class) {if (ticketCount > 0) {try {//小张在出票的时候被领导叫走了//这个时候呢,小刘也要卖这张票//线程睡眠是在模拟网络延迟的情况Thread.sleep(100);} catch (Exception e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "正在售票,剩余" + (--ticketCount));}}}}
}
输出结果
售票员小张正在售票,剩余39
售票员小张正在售票,剩余38
售票员小张正在售票,剩余37
售票员小张正在售票,剩余36
售票员小刘正在售票,剩余35
售票员小刘正在售票,剩余34
售票员小刘正在售票,剩余33
售票员小刘正在售票,剩余32
售票员小刘正在售票,剩余31
售票员小刘正在售票,剩余30
售票员小刘正在售票,剩余29
售票员小刘正在售票,剩余28
售票员小刘正在售票,剩余27
售票员小刘正在售票,剩余26
售票员小刘正在售票,剩余25
售票员小刘正在售票,剩余24
售票员小刘正在售票,剩余23
售票员小刘正在售票,剩余22
售票员小刘正在售票,剩余21
售票员小刘正在售票,剩余20
售票员小张正在售票,剩余19
售票员小张正在售票,剩余18
售票员小刘正在售票,剩余17
售票员小刘正在售票,剩余16
售票员小刘正在售票,剩余15
售票员小刘正在售票,剩余14
售票员小刘正在售票,剩余13
售票员小刘正在售票,剩余12
售票员小刘正在售票,剩余11
售票员小刘正在售票,剩余10
售票员小刘正在售票,剩余9
售票员小刘正在售票,剩余8
售票员小刘正在售票,剩余7
售票员小刘正在售票,剩余6
售票员小刘正在售票,剩余5
售票员小刘正在售票,剩余4
售票员小刘正在售票,剩余3
售票员小刘正在售票,剩余2
售票员小张正在售票,剩余1
售票员小刘正在售票,剩余0
Lock锁使用场景:卖票
class MyThread extends Thread{public static void main(String[] args) {//创建锁对象Lock lock=new ReentrantLock();//创建要执行的任务Ticket ticket=new Ticket(lock);//创建线程并开启线程Thread t1=new Thread(ticket,"售票员张小飞");t1.start();Thread t2=new Thread(ticket,"售票员关小羽");t2.start();}
}class Ticket implements Runnable {private Lock lock;private int count = 40;public Ticket(Lock lock) {this.lock = lock;}@Overridepublic void run() {while (true) {//使用lock锁进行加锁lock.lock();if (count > 0) {try {Thread.sleep(100);System.out.println(Thread.currentThread().getName() + "售出一张票,剩余" + (--count) + "张");} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}else{System.out.println("售票结束");System.exit(0);}}
}
输出结果
售票员张小飞售出一张票,剩余39张
售票员张小飞售出一张票,剩余38张
售票员张小飞售出一张票,剩余37张
售票员张小飞售出一张票,剩余36张
售票员张小飞售出一张票,剩余35张
售票员张小飞售出一张票,剩余34张
售票员张小飞售出一张票,剩余33张
售票员张小飞售出一张票,剩余32张
售票员张小飞售出一张票,剩余31张
售票员张小飞售出一张票,剩余30张
售票员张小飞售出一张票,剩余29张
售票员张小飞售出一张票,剩余28张
售票员张小飞售出一张票,剩余27张
售票员张小飞售出一张票,剩余26张
售票员张小飞售出一张票,剩余25张
售票员张小飞售出一张票,剩余24张
售票员张小飞售出一张票,剩余23张
售票员张小飞售出一张票,剩余22张
售票员张小飞售出一张票,剩余21张
售票员张小飞售出一张票,剩余20张
售票员张小飞售出一张票,剩余19张
售票员张小飞售出一张票,剩余18张
售票员张小飞售出一张票,剩余17张
售票员张小飞售出一张票,剩余16张
售票员张小飞售出一张票,剩余15张
售票员张小飞售出一张票,剩余14张
售票员张小飞售出一张票,剩余13张
售票员张小飞售出一张票,剩余12张
售票员张小飞售出一张票,剩余11张
售票员张小飞售出一张票,剩余10张
售票员张小飞售出一张票,剩余9张
售票员张小飞售出一张票,剩余8张
售票员张小飞售出一张票,剩余7张
售票员张小飞售出一张票,剩余6张
售票员张小飞售出一张票,剩余5张
售票员张小飞售出一张票,剩余4张
售票员张小飞售出一张票,剩余3张
售票员张小飞售出一张票,剩余2张
售票员张小飞售出一张票,剩余1张
售票员张小飞售出一张票,剩余0张
售票结束
我们可以看到使用Lock锁之后,另一线程无法调用run方法,一直处于等待,在尝试运行run()方法几次之后,结束了另一进程。
3、线程优先级
setPriority(int priority)
class MyThread extends Thread{private int countDown = 5;private volatile double d = 0; //同步变量dpublic MyThread(int priority) {setPriority(priority); //设置当前线程优先级start(); //开启当前线程}@Overridepublic String toString() {return super.toString() + ":" + countDown;}@Overridepublic void run() {synchronized(this){while (true){for (int i = 0; i < 5000; i++) {d = d + (Math.PI + Math.E) / i;System.out.println(this);if (--countDown == 0) return;}}}}public static void main(String[] args) {new MyThread(Thread.MAX_PRIORITY);for (int i = 1; i < 5; i++)new MyThread(Thread.MIN_PRIORITY);}
}
输出结果
Thread[Thread-0,10,main]:5
Thread[Thread-1,1,main]:5
Thread[Thread-2,1,main]:5
Thread[Thread-3,1,main]:5
Thread[Thread-1,1,main]:4
Thread[Thread-0,10,main]:4
Thread[Thread-1,1,main]:3
Thread[Thread-3,1,main]:4
Thread[Thread-4,1,main]:5
Thread[Thread-2,1,main]:4
Thread[Thread-4,1,main]:4
Thread[Thread-3,1,main]:3
Thread[Thread-1,1,main]:2
Thread[Thread-0,10,main]:3
Thread[Thread-1,1,main]:1
Thread[Thread-3,1,main]:2
Thread[Thread-4,1,main]:3
Thread[Thread-2,1,main]:3
Thread[Thread-4,1,main]:2
Thread[Thread-3,1,main]:1
Thread[Thread-0,10,main]:2
Thread[Thread-4,1,main]:1
Thread[Thread-2,1,main]:2
Thread[Thread-0,10,main]:1
Thread[Thread-2,1,main]:1
4、死锁问题及解决方案
- 死锁的情形: 多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。
- 死锁产生必要条件:
- 互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用。
- 不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
- 请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
- 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
- 解决死锁方案
一种是synchronized同步锁,另一种是Lock显式锁
为避免死锁,采用信号量控制多线程程序,Semaphore类是用来创建信号量对象的
使用Semaphore控制多线程
public class UnLockTest {public static String obj1 = "obj1";public static final Semaphore a1 = new Semaphore(1); //设置a1信号量为1public static String obj2 = "obj2";public static final Semaphore a2 = new Semaphore(1); //设置a2信号量为1public static void main(String[] args) {LockAa la = new LockAa();new Thread(la).start();LockBb lb = new LockBb();new Thread(lb).start();}
}
class LockAa implements Runnable {public void run() {try {System.out.println(new Date().toString() + " LockA 开始执行");while (true) {//tryAcquire(1, TimeUnit.SECONDS) 1秒尝试请求获取线程许可,TimeUnit.SECONDS 获取秒数if (UnLockTest.a1.tryAcquire(1, TimeUnit.SECONDS)) {System.out.println(new Date().toString() + " LockA 锁住 obj1");//尝试获取a1线程后,尝试获取a2线程if (UnLockTest.a2.tryAcquire(1, TimeUnit.SECONDS)) {System.out.println(new Date().toString() + " LockA 锁住 obj2");Thread.sleep(60 * 1000); // do something}else{System.out.println(new Date().toString() + "LockA 锁 obj2 失败");}}else{System.out.println(new Date().toString() + "LockA 锁 obj1 失败");}UnLockTest.a1.release(); // 释放a1信号量UnLockTest.a2.release(); // 释放a2信号量Thread.sleep(1000); // 马上进行尝试,现实情况下do something是不确定的}} catch (Exception e) {e.printStackTrace();}}
}
class LockBb implements Runnable {public void run() {try {System.out.println(new Date().toString() + " LockB 开始执行");while (true) {if (UnLockTest.a2.tryAcquire(1, TimeUnit.SECONDS)) {System.out.println(new Date().toString() + " LockB 锁住 obj2");if (UnLockTest.a1.tryAcquire(1, TimeUnit.SECONDS)) {System.out.println(new Date().toString() + " LockB 锁住 obj1");Thread.sleep(60 * 1000); // do something}else{System.out.println(new Date().toString() + "LockB 锁 obj1 失败");}}else{System.out.println(new Date().toString() + "LockB 锁 obj2 失败");}UnLockTest.a1.release();UnLockTest.a2.release();Thread.sleep(10 * 1000);}} catch (Exception e) {e.printStackTrace();}}
}
输出结果
Thu Feb 23 02:55:40 CST 2023 LockB 开始执行
Thu Feb 23 02:55:40 CST 2023 LockA 开始执行
Thu Feb 23 02:55:40 CST 2023 LockA 锁住 obj1
Thu Feb 23 02:55:40 CST 2023 LockB 锁住 obj2
Thu Feb 23 02:55:41 CST 2023LockB 锁 obj1 失败
Thu Feb 23 02:55:41 CST 2023LockA 锁 obj2 失败
Thu Feb 23 02:55:42 CST 2023 LockA 锁住 obj1
Thu Feb 23 02:55:42 CST 2023 LockA 锁住 obj2
Thu Feb 23 02:55:51 CST 2023 LockB 锁住 obj2
Thu Feb 23 02:55:51 CST 2023 LockB 锁住 obj1
使用信号量控制多线程锁的步骤
步骤一:创建Semaphore对象
public static String obj1 = "obj1";
public static String obj2 = "obj2";
public static final Semaphore a1 = new Semaphore(1); //设置1个资源数量
public static final Semaphore a2 = new Semaphore(1); //设置1个资源数量
步骤二:显式Lock创建
Lock lock1 = new Lock();
Lock lock2 = new Lock();
步骤三:创建线程
new Thread(lock1).start();
new Thread(lock2).start();
步骤四:线程类创建
class ThreadA implements Runnable{public void run() throws Exception{while(true){if(UnLockTest.a1.tryAcquire(1,TimeUnit.SECONDS)){System.out.println(new Date().toString() + " lock1 锁住 obj1");if(UnLockTest.a2.tryAcquire(1,TimeUnit.SECONDS)){System.out.println(new Date().toString() + " lock1 锁住 obj2");Thread.sleep(60*1000);}}else{System.out.println(new Date().toString() + "lock1 锁 obj1 失败");}UnLockTest.a1.release(); // 释放a1信号UnLockTest.a2.release(); //释放a2信号Thread.sleep(1000); // 空出信号量为ThreadB锁对象obj1,obj2 }}
}
class ThreadB implements Runnable{public void run() throws Exception{while(true){if(UnLockTest.a1.tryAcquire(1,TimeUnit.SECONDS)){System.out.println(new Date().toString() + " lock2 锁住 obj1");if(UnLockTest.a2.tryAcquire(1,TimeUnit.SECONDS)){System.out.println(new Date().toString() + " lock2 锁住 obj2");Thread.sleep(60*1000);}}else{System.out.println(new Date().toString() + "lock2 锁 obj1 失败");}UnLockTest.a1.release(); //释放a1信号UnLockTest.a2.release(); //释放a2信号Thread.sleep(1000); // 空出信号量为ThreadA锁对象obj1,obj2 }}
}
输出结果
Thu Feb 23 03:41:41 CST 2023 LockA 开始执行
Thu Feb 23 03:41:41 CST 2023 LockB 开始执行
Thu Feb 23 03:41:41 CST 2023 LockA 锁住 obj1
Thu Feb 23 03:41:41 CST 2023 LockB 锁住 obj2
Thu Feb 23 03:41:42 CST 2023LockB 锁 obj1 失败
Thu Feb 23 03:41:42 CST 2023LockA 锁 obj2 失败
Thu Feb 23 03:41:43 CST 2023 LockA 锁住 obj1
Thu Feb 23 03:41:43 CST 2023 LockA 锁住 obj2
Thu Feb 23 03:41:52 CST 2023 LockB 锁住 obj2
Thu Feb 23 03:41:52 CST 2023 LockB 锁住 obj1
5、获取线程ID
获取线程ID的方式:getId(),自定义编程ID
public class Main extends Object implements Runnable {private ThreadID var;public Main(ThreadID v) {this.var = v;}public void run() {try {print("var getThreadID =" + var.getThreadID());Thread.sleep(2000);print("var getThreadID =" + var.getThreadID());} catch (InterruptedException x) {}}private static void print(String msg) {String name = Thread.currentThread().getName();System.out.println(name + ": " + msg);}public static void main(String[] args) {ThreadID tid = new ThreadID();Main shared = new Main(tid);try {Thread threadA = new Thread(shared, "threadA");threadA.start();Thread.sleep(500);Thread threadB = new Thread(shared, "threadB");threadB.start();Thread.sleep(500);Thread threadC = new Thread(shared, "threadC");threadC.start();} catch (InterruptedException x) {}}
}//继承ThreadLocal类,是本地线程变量
class ThreadID extends ThreadLocal {private int nextID; //线程ID变量public ThreadID() {nextID = 10001; //初始化线程ID}//同步操作线程IDprivate synchronized Integer getNewID() {Integer id = new Integer(nextID);nextID++;return id;}protected Object initialValue() {print("in initialValue()");return getNewID();}public int getThreadID() {Integer id = (Integer) get();return id.intValue();}private static void print(String msg) {String name = Thread.currentThread().getName();System.out.println(name + ": " + msg);}
}
输出结果
threadA: in initialValue()
threadA: var getThreadID =10001
threadB: in initialValue()
threadB: var getThreadID =10002
threadC: in initialValue()
threadC: var getThreadID =10003
threadA: var getThreadID =10001
threadB: var getThreadID =10002
threadC: var getThreadID =10003
6、线程挂起
Thread.join() 进入挂起状态,即等待激活状态
public class SleepingThread extends Thread {private int countDown = 5;private static int threadCount = 0;public SleepingThread() {super("" + ++threadCount);start();}public String toString() {return "#" + getName() + ": " + countDown;}public void run() {while (true) {System.out.println(this);if (--countDown == 0)return;try {sleep(100);}catch (InterruptedException e) {throw new RuntimeException(e);}}}public static void main(String[] args)throws InterruptedException {for (int i = 0; i < 5; i++)new SleepingThread().join();System.out.println("线程已被挂起");}
}
输出结果
#1: 5
#1: 4
#1: 3
#1: 2
#1: 1
#2: 5
#2: 4
#2: 3
#2: 2
#2: 1
#3: 5
#3: 4
#3: 3
#3: 2
#3: 1
#4: 5
#4: 4
#4: 3
#4: 2
#4: 1
#5: 5
#5: 4
#5: 3
#5: 2
#5: 1
线程已被挂起
7、终止进程
interrupt() ##终止进程
isInterrupt() ##判断是否为终止进程
public class MyThread extends Thread {@Overridepublic void run() {try {sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}}public static void main(String[] args) throws IOException, InterruptedException {Thread thread = new MyThread();thread.start();System.out.println(new Date());System.out.println("50秒之内按任意键中断线程");System.in.read();thread.interrupt(); //提前终止程序thread.join(); //挂起程序System.out.println("程序已退出");System.out.println(new Date());}
}
输出结果
Thu Feb 23 04:27:01 CST 2023
50秒之内按任意键中断线程程序已退出
Thu Feb 23 04:27:02 CST 2023
8、生产者/消费者问题
需要的是什么?
1、共享存储空间 content
class CubbyHole{private int contents; //空间存储量private boolean available = false; //是否可用//获取public synchronized int get(){while(available == false){try{wait();}catch(Exception e){}}available = false;notifyAll();return contents;}public synchronized void put(int value){while(available == true){try{wait();}catch(Exception e){}}contents = values;available = true;notifyAll();}
}
2、生产者线程 producter
class Consumer extends Thread{private CubbyHole cubbyhole;private int number;public Consumer(CubbyHole c,int number){cubbyhole = c;this.number = number;}public void run(){int value = 0;for(int i = 0;i<10;i++){value = cubbyhole.get();System.out.println("消费者 #" + this.number+ " got: " + value);}}
}
3、消费者线程 consumer
public Producer extends Thread{private CubbyHole cubbyhole;private int number;public Producer(CubbyHole c,int number){cubbyhole = c;this.number = number;}public void run(){for(int i = 0; i < 10 ; i++){cubbyhole.put(i);System.out.println("生产者 #" + this.number + " put: " + i);try {sleep((int)(Math.random() * 100));} catch (InterruptedException e) { }}}
}
输出结果
消费者 #1 got: 0
生产者 #1 put: 0
生产者 #1 put: 1
消费者 #1 got: 1
生产者 #1 put: 2
消费者 #1 got: 2
生产者 #1 put: 3
消费者 #1 got: 3
生产者 #1 put: 4
消费者 #1 got: 4
生产者 #1 put: 5
消费者 #1 got: 5
生产者 #1 put: 6
消费者 #1 got: 6
生产者 #1 put: 7
消费者 #1 got: 7
生产者 #1 put: 8
消费者 #1 got: 8
生产者 #1 put: 9
消费者 #1 got: 9
相关文章:
Java实例——线程
1、查看线程存活状态 Thread.isAlive() Thread.getName() public class MyThread extends Thread{Overridepublic void run() {for (int i 0; i < 10; i) {printMsg();}}public static void printMsg(){Thread thread Thread.currentThread();//Thread.getName() 获取线程…...

云计算学习课程——越来越重要的云安全
2023,越来越多的企业和组织正在或即将把核心系统和数据迁移上云端,其中以公有云和服务居多,那么就意味着在数据迁移的过程中会出现安全问题的几率更大。企业也越来越注重云安全体系,对我们云计算运维工程师来说,也是一…...

Android 高性能列表:RecyclerView + DiffUtil
文章目录背景介绍一般刷新 notifyDataSetChanged()局部刷新实现调用代码准备工作创建 MyDiffUtilCallback 类继承 DiffUtil.Callback 抽象类MyAdpter 类代码实现步骤总结通过 log 证实 diffutil 的局部刷新diffutil 优化后台线程参考主线程参考diff 更新优化后写法相关参考背景…...
为什么派生类的构造函数必须在初始化列表中调用基类的构造函数
调用派生类的构造函数时,可能会调用继承自基类的函数,也就可能会用到基类的数据成员,因此,调用派生类的构造函数时,必须确保继承自基类的数据成员已构造完毕,而将基类构造函数的调用写在初始化列表中&#…...

2023年2月初某企业网络工程师面试题【建议收藏】
拓扑图如下,主机A与主机B能互相通信,但是A不能ping通RA的F0接口,这是为什么?RA上f0接口上配置了ACL,禁止源ip为主机A,目的ip为RA f0的数据包的发送; 第一个路由器上只有到主机B网段的路由&#…...
分布式下(sso)单点登录
目录标题一、基于rediscookie的单点登录二、基于jwtcookie的单点登录一、基于rediscookie的单点登录 传统单机应用登录 传统单机应用,一般是结合session和cookie实现认证、授权。用户通过输入账号密码登录系统,登录成功后在系统创建一个session来保存用…...

PMP真的有那么厉害?你需要考PMP吗?
这个含金量是有的,是目前项目管理界含金量较高的证书,但也要分人, 因为这是职业证书,主要用于提高职场工作能力,不搞这一行的,PMP证书含金量再高也是一张废纸,可以看下下面这张图,这…...

高通平台开发系列讲解(WIFI篇)802.11 基本概念
文章目录 一、WLAN概述二、802.11发展历程三、802.11基本概念沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本文将基于高通平台介绍802.11基本概念。 一、WLAN概述 WLAN是Wireless Local Area Network的简称,指应用无线通信技术将计算机设备互联起来,构成可以互相通…...

扬帆优配|反弹涨超70%,昨收三连板,稀土行业或迎大事件
本年第一批稀土挖掘锻炼目标行将发放。 2月22日晚,东易日盛公告称,公司收到董事、副总经理兼财务总监李双侠出具的《关于未严格执行股份减持方案的致歉函》,其此次减持方案已施行结束,但在施行减持方案时,因操作失误&a…...
华为OD机试 - 工号不够用了(Java) | 机试题+算法思路+考点+代码解析 【2023】
工号不够用了 3020年,空间通信集团的员工人数突破20亿人,即将遇到现有工号不够用的窘境。 现在,请你负责调研新工号系统。继承历史传统,新的工号系统由小写英文字母(a-z)和数字(0-9)两部分构成。新工号由一段英文字母开头,之后跟随一段数字,比如"aaahw0001&qu…...

Python学习-----lambda式匿名函数
目录 前言: 1.什么是lambda函数 2.使用示例 (1)示例1:与def对比 (2)示例2:与三目运算符 (3)示例3:lambda作为参数传入其他函数 (4ÿ…...
华为OD机试真题Python实现【求解连续数列】真题+解题思路+代码(20222023)
求解连续数列 题目 已知连续正整数数列{K}=K1,K2,K3… Ki的各个数相加之和为S, i = N (0 < S < 100000, 0 < N < 100000), 求此数列K。 🔥🔥🔥🔥🔥👉👉👉👉👉👉 华为OD机试(Python)真题目录汇总 ## 输入 输入包含两个参数 连续正整数数…...

每日学术速递2.22
CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.PriSTI: A Conditional Diffusion Framework for Spatiotemporal Imputation 标题:PriSTI:时空插补的条件扩散框架 作者:Mingzhe Liu, Han Huan…...

postgresql 数据库 主从切换 测试
postgresql 数据库 主从切换 测试 文章目录postgresql 数据库 主从切换 测试前言环境:主从切换1. 查看数据库状态:2. 备库切换主库3. 旧主库切换成备库;4 查看状态后记前言 因数据库等保需要,需要对老系统的数据库进行主从切换来…...

干旱预测方法总结及基于人工神经网络的干旱预测案例分析(MATLAB全代码)
本案例采用SPEI干旱指数,构建ANN和BP神经网络预测模型,并开展1~3个月预见期的干旱预测,对比分析干旱预测模型的适用性,为流域干旱预警和管理提供技术依据。 干旱预测 1 干旱预测方法 1.1 统计学干旱预测 根据历史降水或气温等…...

一篇文章弄清楚啥是数组和集合
数组和集合多语言都有,数组是集合的一种,是一种有序的集合,不面向对象,面向过程的也有。1.数组逻辑结构:线性的物理结构:顺序的存储结构申请内存:一次申请一大段连续的空间,一旦申请…...

计算机网络(五):三次握手和四次挥手,TCP,UDP,TIME-WAIT,CLOSE-WAIT,拥塞避免,
文章目录零. TCP和UDP的区别以及TCP详解TCP是如何保证可靠性的TCP超时重传的原理TCP最大连接数限制TCP流量控制和拥塞控制流量控制拥塞控制TCP粘包问题一、三次握手和四次挥手二、为什么要进行三次握手?两次握手可以吗?三、为什么要进行四次挥手…...

【数据结构】二叉树(C语言实现)
文章目录一、树的概念及结构1.树的概念2.树的相关概念名词3.树的表示4.树在实际中的运用二、二叉树概念及结构1.二叉树的概念2.特殊的二叉树3.二叉树的性质4.二叉树的存储结构三、二叉树链式结构的实现1.结构的定义2.构建二叉树3.二叉树前序遍历4.二叉树中序遍历5.二叉树后序遍…...

高级信息系统项目管理(高项 软考)原创论文——成本管理(2)
1、如果您想了解如何高分通过高级信息系统项目管理师(高项)你可以点击链接: 高级信息系统项目管理师(高项)高分通过经验分享_高项经验 2、如果您想了解更多的高级信息系统项目管理(高项 软考)原创论文,您可以点击链接:...

代码签名即将迎来一波新关注
在数字化高度发展的当下,个人隐私及信息安全保护已经成了大家关注的重点,包括日常使用的电脑软件,手机APP等,由于包含了大量的用户信息,已经成了重点关注对象,任何一个疏忽就可能泄露大量用户信息。所以权威…...

IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...