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等,由于包含了大量的用户信息,已经成了重点关注对象,任何一个疏忽就可能泄露大量用户信息。所以权威…...

黑盒渗透盲打lampiao
一、查找主机ip,通过Nmap扫描工具排查出我的靶机的IP 为.134 python tools.py ip -i 192.168.12.0 -h 254 -l 1 二、扫描其他端口。 1898 三、查看网站漏洞情况,典型的漏洞特征 Ac扫描漏洞情况,利用典型的漏洞。 四、开始getshell 1、启动M…...

笔记:VLAN及交换机处理详细教程(Tagged, UnTagged and Native VLANS Tutorial)
一、内容来源 本文是对下面这篇文章的总结,写的很全、很细致、干货满满,强力推荐: 《Tagged, UnTagged and Native VLANS Tutorial – A Quick Guide about What they Are?》 二、为什么引入VLAN? 早期设备间通过集线器&#x…...

在字节跳动,造赛博古籍
“你在字节跳动哪个业务?”“古籍数字化。把《论语》《左传》《道德经》这些古籍变成电子版,让大家都能免费看。”没错,除了你熟悉的那些 App,字节跳动还在做一些小众而特别的事情,古籍数字化就是其中之一。在字节跳动…...

Android 12.0设置默认Launcher安装一款Launcher默认Launcher无效的解决方案
1.概述 在12.0的系统rom定制化过程中,在系统中当有多个Launcher的时候,这时候会要求设置默认Launcher,但是在最近的产品开发过程中,发现在设置完默认Launcher以后,在安装个Launcher的时候,会让原来设置的默认Launcher变为空了,就是在系统Settings中的默认应用中,launche…...

数据结构第16周 :( 希尔排序+ 堆排序 + 快速排序 )
目录希尔排序堆排序快速排序希尔排序 【问题描述】给出一组数据,请用希尔排序将其按照从小到大的顺序排列好。 【输入形式】原始数据,以0作为输入的结束;第二行是增量的值,都只有3个。 【输出形式】每一趟增量排序后的结果 【…...

【C++】类和对象
1.面向过程和面向对象初步认识 我们知道,C语言是面向过程的,关注的就是问题解决的过程; C是面向过程和面向对象混编,因为C兼容了C语言,而面向对象关注的不再是问题解决的过程; 而是一件事情所关联的不同…...

Java缓存面试题——Redis应用
文章目录1、为什么要使用Redis做缓存?2、为什么Redis单线程模型效率也能那么高?3、Redis6.0为什么要引入多线程呢?4、Redis常见数据结构以及使用场景字符串(String)哈希(Hash)列表(list)集合&am…...

KMP算法详细理解
一、目的1.KMP应用场景:可以解决字符串匹配问题; 在一个串中查找是否出现过另一个串。2.KMP的经典思想就是:当出现字符串不匹配时,可以记录一部分之前已经匹配的文本内容,利用这些信息避免从头再去做匹配。3.KMP算法关键在于&…...

RabbitMQ单节点安装
在学习RabbitMQ之前,必须要把RabbitMQ的环境搭建起来,刚开始学习时,搭建单节点是入门RabbitMQ最方便、最快捷的方式,这篇文章就是介绍如何使用RabbitMQ压缩包的方式搭建一个单节点的RabbitMQ。 在实际项目中,服务器都…...

tomcat 服务的目录结构和tomcat的运行模式
目录 一、tomcat 服务的目录结构解析: 1、tomcat目录结构: bin目录: conf目录: lib目录: logs目录: temp目录: webapps目录: wokr目录: 二、tomcat服务的运行模…...