Day22
Day22
一,生产者消费者模型
1.1,单个生产者单个消费者
public class Test01 {/*** 知识点:生产者消费者模型 - 单个生产者单个消费者* * 分析:* 产品类 - Phone:属性(brand,price)* 生产者线程 - Producer* 消费者线程 - Consumer* 最终的目的:生产一个、消费一个* * 步骤:* 1.多个线程(生产者线程、消费者线程)操作同一个资源(产品类的对象)* 2.多个产品之间来回切换(华为 <--> 小米)* null -- 0.0* 华为 -- 0.0* 小米 -- 3999* 华为 -- 1999* 脏数据的解决思路:加锁* 3.生产一个消费一个* */public static void main(String[] args) {//brand - null//price - 0.0Phone phone = new Phone();Producer p = new Producer(phone);Consumer c = new Consumer(phone);p.start();c.start();}
}
//产品类
public class Phone {private String brand;private double price;private boolean store;public Phone() {}public Phone(String brand, double price) {this.brand = brand;this.price = price;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public boolean isStore() {return store;}public void setStore(boolean store) {this.store = store;}@Overridepublic String toString() {return "Phone [brand=" + brand + ", price=" + price + "]";}
}
//生产者线程
public class Producer extends Thread{private Phone phone;public Producer(Phone phone) {this.phone = phone;}@Overridepublic void run() {boolean flag = true;while(true){synchronized(phone){if(phone.isStore()){//有库存//等待//1.将当前线程记录在对象监视器中(记录当前线程进入到阻塞状态)//2.释放锁资源(解锁)//3.当前线程进入到阻塞状态try {phone.wait();} catch (InterruptedException e) {e.printStackTrace();}}if(flag){phone.setBrand("华为");phone.setPrice(3999);}else{phone.setBrand("小米");phone.setPrice(1999);}flag = !flag;phone.setStore(true);//唤醒:唤醒的是对象监视器中随机一个等待的线程,唤醒的线程进入到就绪态phone.notify();}}}
}
//消费者线程
public class Consumer extends Thread{private Phone phone;public Consumer(Phone phone) {this.phone = phone;}@Overridepublic void run() {while(true){synchronized(phone){if(!phone.isStore()){//没有库存try {//等待://1.将当前线程记录在对象监视器中(记录当前线程进入到阻塞状态)//2.释放锁资源(解锁)//3.当前线程进入到阻塞状态phone.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(phone.getBrand() + " -- " + phone.getPrice());phone.setStore(false);//唤醒:唤醒的是对象监视器中随机一个等待的线程,唤醒的线程进入到就绪态phone.notify();}}}
}
1.2,多个生产者多个消费者
public class Test01 {/*** 知识点:生产者消费者模型 - 多个生产者多个消费者* * 分析:* 产品类 - Phone:属性(brand,price)* 生产者线程 - Producer* 消费者线程 - Consumer* 最终的目的:生产一个、消费一个* * 步骤:* 1.多个线程(生产者线程、消费者线程)操作同一个资源(产品类的对象)* 2.多个产品之间来回切换(华为 <--> 小米)* null -- 0.0* 华为 -- 0.0* 小米 -- 3999* 华为 -- 1999* 脏数据的解决思路:加锁* 3.生产一个消费一个* */public static void main(String[] args) {//brand - null//price - 0.0Phone phone = new Phone();Producer p1 = new Producer(phone);Producer p2 = new Producer(phone);Consumer c1 = new Consumer(phone);Consumer c2 = new Consumer(phone);p1.start();p2.start();c1.start();c2.start();}
}
//生产者线程
public class Producer extends Thread{private Phone phone;public Producer(Phone phone) {this.phone = phone;}@Overridepublic void run() {boolean flag = true;while(true){synchronized(phone){while(phone.isStore()){//有库存//等待//1.将当前线程记录在对象监视器中(记录当前线程进入到阻塞状态)//2.释放锁资源(解锁)//3.当前线程进入到阻塞状态try {phone.wait();} catch (InterruptedException e) {e.printStackTrace();}}if(flag){phone.setBrand("华为");phone.setPrice(3999);}else{phone.setBrand("小米");phone.setPrice(1999);}flag = !flag;phone.setStore(true);//唤醒:唤醒对象监视器中所有的线程phone.notifyAll();}}}
}
//产品类
public class Phone {private String brand;private double price;private boolean store;public Phone() {}public Phone(String brand, double price) {this.brand = brand;this.price = price;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public boolean isStore() {return store;}public void setStore(boolean store) {this.store = store;}@Overridepublic String toString() {return "Phone [brand=" + brand + ", price=" + price + "]";}
}
//消费者线程
public class Consumer extends Thread{private Phone phone;public Consumer(Phone phone) {this.phone = phone;}@Overridepublic void run() {while(true){synchronized(phone){while(!phone.isStore()){//没有库存try {//等待://1.将当前线程记录在对象监视器中(记录当前线程进入到阻塞状态)//2.释放锁资源(解锁)//3.当前线程进入到阻塞状态phone.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(phone.getBrand() + " -- " + phone.getPrice());phone.setStore(false);//唤醒:唤醒对象监视器中所有的线程phone.notifyAll();}}}
}
区别就是只有一个生产者和消费者的时候不需要一直去判断有没有库存,因为生产了才能消费,消费了才生产
二,仓储模型
2.1一个生产者一个消费者
public class Test01 {/*** 知识点:仓储模型 - 一个生产者一个消费者* * 分析:* 产品类 - Cake(brand、price、datetime)* 仓库类 - Store(maxCapacity、curCapacity、list)* 生产者线程 - Producer* 消费者线程 - Consumer* 注意:先生产的先卖出 -- 队列模式* * 经验:对象监视器如何选择?* 锁对象* */public static void main(String[] args) {Store store = new Store();Producer p = new Producer(store);Consumer c = new Consumer(store);p.start();c.start();}
}
import java.util.LinkedList;
//仓库类
public class Store {private static final int DEFAULT_INIT_CAPACITY = 20;private int maxCapacity;private int curCapacity;private LinkedList<Cake> list;public Store() {maxCapacity = DEFAULT_INIT_CAPACITY;list = new LinkedList<>();}public Store(int maxCapacity) {this.maxCapacity = maxCapacity;list = new LinkedList<>();}//入库public synchronized void push(Cake cake){if(curCapacity >= maxCapacity){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.add(cake);curCapacity++;System.out.println("入库,当前库存为:" + curCapacity);this.notify();}//出库public synchronized Cake pop(){if(curCapacity <= 0){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}Cake cake = list.removeFirst();curCapacity--;System.out.println("出库,当前的库存为:" + curCapacity + ",卖出的产品是:" + cake);this.notify();return cake;}}
//生产与存储对象类
public class Cake {private String brand;private double price;private String datetime;public Cake() {}public Cake(String brand, double price, String datetime) {this.brand = brand;this.price = price;this.datetime = datetime;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}public String getDatetime() {return datetime;}public void setDatetime(String datetime) {this.datetime = datetime;}@Overridepublic String toString() {return "Cake [brand=" + brand + ", price=" + price + ", datetime=" + datetime + "]";}
}
import java.time.LocalDateTime;
//生产者类
public class Producer extends Thread{private Store store;public Producer(Store store) {this.store = store;}@Overridepublic void run() {while(true){Cake cake = new Cake("桃李蛋糕", 2.5, LocalDateTime.now().toString());store.push(cake);}}
}
//消费者类
public class Consumer extends Thread{private Store store;public Consumer(Store store) {this.store = store;}@Overridepublic void run() {while(true){store.pop();}}
}
2.2,多个生产者多个消费者
只需把仓库类的出库入库的判断改为while循环即测试类多几个生产,消费线程,其他同上
import java.util.LinkedList;public class Store {private static final int DEFAULT_INIT_CAPACITY = 20;private int maxCapacity;private int curCapacity;private LinkedList<Cake> list;public Store() {maxCapacity = DEFAULT_INIT_CAPACITY;list = new LinkedList<>();}public Store(int maxCapacity) {this.maxCapacity = maxCapacity;list = new LinkedList<>();}//入库public synchronized void push(Cake cake){while(curCapacity >= maxCapacity){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}list.add(cake);curCapacity++;System.out.println("入库,当前库存为:" + curCapacity);this.notifyAll();}//出库public synchronized Cake pop(){while(curCapacity <= 0){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}Cake cake = list.removeFirst();curCapacity--;System.out.println("出库,当前的库存为:" + curCapacity + ",卖出的产品是:" + cake);this.notifyAll();return cake;}
}
//测试类
public class Test01 {/*** 知识点:仓储模型 - 多个生产者多个消费者* * 分析:* 产品类 - Cake(brand、price、datetime)* 仓库类 - Store(maxCapacity、curCapacity、list)* 生产者线程 - Producer* 消费者线程 - Consumer* 注意:先生产的先卖出 -- 队列模式* * 经验:对象监视器如何选择?* 锁对象* */public static void main(String[] args) {Store store = new Store();Producer p1 = new Producer(store);Producer p2 = new Producer(store);Consumer c1 = new Consumer(store);Consumer c2 = new Consumer(store);p1.start();p2.start();c1.start();c2.start();}
}
三,线程池
//任务类
public class Task implements Runnable{private int num;public Task(int num) {this.num = num;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "去执行任务" + num);}}
1,创建单个线程的线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class Test01 {/*** 知识点:使用JDK1.8自带的线程池*/public static void main(String[] args) {//创建单个线程的线程池ExecutorService pool = Executors.newSingleThreadExecutor();for (int i = 1; i <= 100; i++) {Task task = new Task(i);//将任务提交给线程池pool.execute(task);}//关闭线程池pool.shutdown();}
}
2,创建指定线程个数的线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class Test02 {/*** 知识点:使用JDK1.8自带的线程池*/public static void main(String[] args) {//创建指定线程个数的线程池ExecutorService pool = Executors.newFixedThreadPool(3);for (int i = 1; i <= 100; i++) {Task task = new Task(i);//将任务提交给线程池pool.execute(task);}//关闭线程池pool.shutdown();}
}
3,创建可缓存的线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class Test03 {/*** 知识点:使用JDK1.8自带的线程池*/public static void main(String[] args) {//创建可缓存的线程池(原本线程池中没有线程,有任务就创建线程,60秒工作的线程任务是闲置线程,就回收)ExecutorService pool = Executors.newCachedThreadPool();for (int i = 1; i <= 100; i++) {Task task = new Task(i);//将任务提交给线程池pool.execute(task);}//关闭线程池pool.shutdown();}
}
4,创建延迟任务的线程池
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;public class Test04 {/*** 知识点:使用JDK1.8自带的线程池*/public static void main(String[] args) throws InterruptedException {//创建延迟任务的线程池ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);for (int i = 1; i <= 100; i++) {Task task = new Task(i);//提交任务,设置延迟时间pool.schedule(task, 5, TimeUnit.SECONDS);}//关闭线程池pool.shutdown();}
}
四,自定义线程
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class Test01 {/*** 知识点:自定义线程池*/public static void main(String[] args) {//自定义线程池ThreadPoolExecutor pool = new ThreadPoolExecutor(5, //核心线程数20, //最大线程数60, //闲置时间TimeUnit.SECONDS, //时间单位new ArrayBlockingQueue<>(30), //任务队列 - 有界队列new ThreadFactory() {//自定义线程工程int num = 1;@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r);t.setName("最牛逼的线程" + num);t.setPriority(Thread.MAX_PRIORITY);num++;return t;}}, new RejectedExecutionHandler() {//自定义拒绝策略@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {System.out.println("傻逼,你提交的任务太快了~~~");}});for (int i = 1; i <= 100; i++) {Task task = new Task(i);//将任务提交给线程池pool.execute(task);}//闲置时间到后,会销毁核心线程的方法//注意:如果连核心线程都销毁了,何谈线程的复用率?pool.allowCoreThreadTimeOut(true);pool.shutdown();}
}
public class Task implements Runnable{private int num;public Task(int num) {this.num = num;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + "去执行任务" + num);}
}
.
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;public class Test01 {/*** 知识点:自定义线程池*/public static void main(String[] args) {MyThreadPool pool = new MyThreadPool(5, 20, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(30));for (int i = 1; i <= 100; i++) {Task task = new Task(i);//将任务提交给线程池pool.execute(task);}pool.shutdown();}
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class MyThreadPool extends ThreadPoolExecutor{private static final MyThreadFactory myThreadFactory = new MyThreadFactory();private static final MyRejectedExecutionHandler myRejectedExecutionHandler = new MyRejectedExecutionHandler();public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, myThreadFactory, myRejectedExecutionHandler);}public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);}//自定义拒绝策略private static class MyRejectedExecutionHandler implements RejectedExecutionHandler{@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {System.out.println("哎呀,你提交的任务太快了~~~");}}//自定义线程工程private static class MyThreadFactory implements ThreadFactory{int num = 1;@Overridepublic Thread newThread(Runnable r) {Thread t = new Thread(r);t.setName("最厉害的线程" + num);t.setPriority(Thread.MAX_PRIORITY);num++;return t;}}}
五,死锁
小结:
1.死锁不会报错,程序会一直抢资源
2.尽可能不要锁嵌套
public class Test01 {/*** 知识点:死锁* */public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {synchronized (KuaiZi.a) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}synchronized (KuaiZi.b) {System.out.println("哲学家1吃饭饭");}}}}).start();new Thread(new Runnable() {@Overridepublic void run() {synchronized (KuaiZi.b) {try {Thread.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}synchronized (KuaiZi.a) {System.out.println("哲学家2吃饭饭");}}}}).start();}
}class KuaiZi{public static Object a = new Object();public static Object b = new Object();
}
六,带返回值得任务类(补Day21)
//注意MyThreadPool是我上面自写的线程池
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
//导入你自己路径上的
import com.qf.thread_pool_03.MyThreadPool;public class Test01 {/*** 需求:计算任务,一个包含了2万个整数的数组,分拆了多个线程来进行并行计算,最后汇总出计算的结果。* * 使用带有返回值的任务类去解决该需求
s */public static void main(String[] args) throws InterruptedException, ExecutionException {//创建数组int[] arr = new int[20000];//初始化数组中的元素for (int i = 0; i < arr.length; i++) {arr[i] = i+1;}//创建线程池MyThreadPool pool = new MyThreadPool(4, 4, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(30));//创建任务Task task1 = new Task(arr, 0, 5000);Task task2 = new Task(arr, 5000, 10000);Task task3 = new Task(arr, 10000, 15000);Task task4 = new Task(arr, 15000, 20000);//提交任务,返回Future,任务的返回值就在Future里Future<Integer> future1 = pool.submit(task1);Future<Integer> future2 = pool.submit(task2);Future<Integer> future3 = pool.submit(task3);Future<Integer> future4 = pool.submit(task4);//合并计算System.out.println(future1.get() + future2.get() + future3.get() + future4.get());pool.shutdown();}
}
import java.util.concurrent.Callable;//带有返回值的任务类
public class Task implements Callable<Integer>{private int[] arr;private int startIndex;private int endIndex;public Task(int[] arr, int startIndex, int endIndex) {this.arr = arr;this.startIndex = startIndex;this.endIndex = endIndex;}@Overridepublic Integer call() throws Exception {int sum = 0;for (int i = startIndex; i < endIndex; i++) {sum += arr[i];}return sum;}
}
相关文章:
Day22
Day22 一,生产者消费者模型 1.1,单个生产者单个消费者 public class Test01 {/*** 知识点:生产者消费者模型 - 单个生产者单个消费者* * 分析:* 产品类 - Phone:属性(brand,price)* 生产者线程 - Producer* 消费者线程 - Consumer* …...
Windows下linux 子系统 WSL2怎样使用usb串口(USBIPD-win4.0.0)
Windows下linux 子系统 WSL2怎样使用usb串口(USBIPD-win4.0.0) 一、widows安装二、ubuntu安装三、widows配置四、wsl配置 一、widows安装 https://github.com/dorssel/usbipd-win 直接下载最新版本的msi文件安装 二、ubuntu安装 sudo apt install lin…...
飞腾Ubantu22.04.3安装OpenNebula测试
1.概述 因OpenneBula官方镜像源只有AMD架构的镜像包不存在ARM的镜像包,借此用源码编译进行测试。 2.官网github地址 下载解压存放在服务器上: https://github.com/OpenNebula/minione/blob/master文件目录: 3.安装依赖包 sudo apt -y …...
gookit/color - Go语言命令行色彩使用库教程
gookit/color - Go语言命令行色彩使用库教程 1.安装2.基础颜色(16-color)3.256色彩/RGB风格 1.安装 go get github.com/gookit/color2.基础颜色(16-color) 提供通用的API方法:Print Printf Println Sprint Sprintf 1、例如: color.Yellow.Println(&q…...
python弹奏《起风了》
代码是很大的! 其实就是python用ctypes调用Win API import ctypes import threading import time winmm = ctypes.windll.winmmclass Scale:Rest = 0C8 = 108B7 = 107A7s = 106A7 = 105G7s = 104G7 = 103F7s = 102F7 = 101E7 = 100D7s = 99D7 = 98C7s = 97C7 = 96B6 = 95A6s…...
Linux---all
Linux常用命令: Linux常用命令-CSDN博客 Linux命令大全(超详细版)_linux命令行大全-CSDN博客Linux常用命令大全(非常全面)-CSDN博客Linux 命令大全(看这一篇就足够)_linux命令-CSDN博客Linux常用命令大全——赶紧收藏…...
前端中级算法题
前端中级算法题 反转字符串 编写一个函数,接受一个字符串作为输入,并返回反转后的字符串。 示例: function reverseString(str) {return str.split().reverse().join(); }reverseString(hello); // 输出: olleh 找出数组中的最大值 编写一个函…...
Ant Design Vue 编译后的网页特点是什么,怎么确认他是用的前端 Ant Design Vue 技术栈的呢?
Ant Design Vue 是一个前端 UI 框架,使用 Vue.js 构建。它包含了大量的预设样式和组件,如按钮、表单、表格等,可以帮助开发者快速构建出优雅且功能丰富的网页。但是,要确定一个编译后的网页是否使用了 Ant Design Vue,…...
python | PYTHON正则表达式
操作符说明实例.表示任何单个字符[]字符集,对单个字符给出取值范围[abc]表示a、b、c,[a-z]表示a到z单个字符[^ ]非字符集,对单个字符给出排除范围[^abc]表示非a或b或c的单个字符*前一个字符0次或无限次扩充abc* 表示ab,abc&#x…...
为什么大学c语言课不顺便教一下Linux,Makefile
为什么大学c语言课不顺便教一下Linux,Makefile,git,gdb等配套工具链呢? 在开始前我有一些资料,是我根据自己从业十年经验,熬夜搞了几个通宵,精心整理了一份「Linux的资料从专业入门到高级教程工具包」&…...
Go后端开发 -- main函数 变量 常量 函数
Go后端开发 – main函数 & 变量 & 常量 & 函数 文章目录 Go后端开发 -- main函数 & 变量 & 常量 & 函数一、第一个main函数1.创建工程2.main函数解析 二、变量声明1.单变量声明2.多变量声明 三、常量1.常量的定义2.优雅的常量 iota 四、函数1.函数返回…...
2023/12/30 c++ work
定义一个Person类,私有成员int age,string &name,定义一个Stu类,包含私有成员double *score,写出两个类的构造函数、析构函数、拷贝构造和拷贝赋值函数,完成对Person的运算符重载(算术运算符、条件运算…...
ctfshow——文件上传
文章目录 文件上传思路web 151web 152web 153知识点解题 web 154web 155web 156web 157web 158web 159web160web 161 文件上传思路 web 151 打开页面显示:前台校验不可靠。说明这题是前端验证。 右键查看源代码,找到与上传点有关的前端代码:…...
【RocketMQ每日一问】RocketMQ SQL92过滤用法以及原理?
1.生产端 public class SQLProducer {public static int count 10;public static String topic "xiao-zou-topic";public static void main(String[] args) {DefaultMQProducer producer MQUtils.createLocalProducer();IntStream.range(0, count).forEach(i -&g…...
Go语言中的包管理工具之Go Path的使用
GoLang 中常用的包管理的方式 1 )概述 常用的有三种 Go PathGo VendorGo Modules 2 )发展历程 早期go的包管理存在很大缺陷,甚至可以说没有官方统一的包管理工具 一方面官方在努力发布一些实验性的包管理工具。同时也出现了很多社区开发…...
cocos creator(2.4.7版本) webview 可以在上层添加UI控件
实现原理:cocos本身在平台中属于view,所以可以把webview放在底层,以达到目标。 实现过程:参考 cocos creator(2.4.7版本) videoplayer 可以在上层添加UI控件() 需要增加以下过程: …...
2023 年四川省职业院校技能大赛“信息安全管理与评估”样题
2023 年四川省职业院校技能大赛(高等职业教育) “信息安全管理与评估”样题 竞赛需要完成三个阶段的任务,分别完成三个模块,总分共计 1000分。三个模块内容和分值分别是: 第一阶段:模块一 网络平台搭建与设…...
ubuntu2204,mysql8.x安装
ubuntu 2204, MySQL8.x安装 sudo apt-get update sudo apt-get upgrade# 习惯性的先设置一下时区,这里我使用东八区 date -R # 若发现时间正常则无需设置tzselect# 依次选择 4 -> 10 -> 1 -> 1cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtimedate -R# 同步时间…...
CG Magic分享云渲染和本地渲染之间的区别有什么?
无论是效果图渲染还是影视渲染,对于3D设计师来说都是常见的渲染方式就是云渲染和本地渲染。 本地电脑渲染是指将渲染任务分配给本地计算机进行处理,而云渲染是指将渲染任务上传至云端服务器进行处理。 对于一些初入行业的新手朋友来说,会在想…...
【算法与数据结构】763、LeetCode划分字母区间
文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析:本题要求为: 1.尽可能多的划分片段2.字母只能出现在一个片段中3.片段连接起来仍然是s&…...
新火种AI|人形机器人敲响上市罗,首日市值高达390亿港元
作者:一号 编辑:彩云 史上第一次!人形机器人在港交所和人类一起敲锣。 12月29日,在港交所现场,熊猫机器人优悠走上舞台,将手中的锣锤递给了优必选创始人、董事长兼CEO周剑,而同周剑一同准…...
SpringMVC框架
SpringMVC 三层架构MVC模式SpringMVC入门案例总结 三层架构 表现层(web) 页面数据的收集,产出页面 业务逻辑层(service) 业务处理 数据访问层(Dao) 数据持久化 MVC模式 SpringMVC 基于Java…...
FreeRTOS——计数型信号量知识总结及实战
1计数型信号量概念 1)计数型信号量相当于队列长度大于1 的队列,因此计数型信号量能够容纳多个资源 2)适用场景: 事件计数: 当每次事件发生后,在事件处理函数中释放计数型信号量(计数值1&#x…...
Linux下Docker Engine安装后的一些配置步骤
一些安装后的配置令Linux主机可以更好地与Docker配合使用。 0x01 以非root用户身份管理Docker Docker守护进程绑定到Unix套接字,而不是TCP端口。默认情况下,root用户拥有Unix套接字,而其他用户只能使用 sudo. Docker守护进程始终以root用户身份运行。 …...
【并发设计模式】聊聊Balking是如何实现以及具体原理
前面的等待唤醒,其实是一个线程等待执行满足条件的逻辑,会一直死等,但是并不是全部的场景都需要死等。比如我们去坐车的时候,公交一直没来,那么就可以不去了。而等待唤醒是公交没来我就等他来了再去。 Guarded Suspen…...
dubbo的一些问题思考
1.dubbo是啥 Dubbo 是一个高性能的 Java RPC(远程过程调用)框架,用于构建分布式服务架构。由阿里巴巴开发并开源,作为一个分布式服务框架,Dubbo 提供了丰富的功能,包括服务治理、远程调用、负载均衡、容错机…...
盛最多水的容器(力扣11题)
例题: 分析: 这道题给出了一个数组,数组里的元素可以看成每一个挡板,要找到哪两个挡板之间盛的水最多,返回盛水量的最大值。这其实是一个双指针问题。 我们可以先固定第一个挡板( i )和最后一个挡板( j ),…...
.babky勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
导言: 网络安全威胁不断进化,其中.babky勒索病毒引起了广泛关注。这篇文章91数据恢复将深入介绍.babky的狡猾特征,以及在遭受其袭击时如何高效地恢复被加密的数据,并提供实用的预防方法。当面对被勒索病毒攻击导致的数据文件加密…...
20240103-通过布局让自己的生活有有意义人生有价值
最近听到看到的一些词 心力、稀缺、卓有成效、知行合一、致良知、心即理、事上练 最近琢磨出这么一个道理,就是任何人做事情其实都有内心趋势和一套适合他自己的内心驱动的方法。我们经常意识不到,我时常也会去寻求做一件事,是不是有特定的…...
JDK17 - 开发者视角,从 JDK8 ~ JDK17 都增加了哪些新特性
目录 前言 一、站在开发视角,从 JDK8 升级到 JDK17 都有哪些新特性 1.1、JDK8 新特性 1.1.1、Optional 类 a)简介 b)使用方法 c)使用场景 1.2、JDK9 新特性 1.2.1、Optional - ifPresentOrElse 解决 if-else 1.2.2、Opt…...
临沂建手机网站公司/上海职业技能培训机构
jdbc statement的说法 1.Statement、PreparedStatement和CallableStatement都是接口(interface)。 2.Statement继承自Wrapper、PreparedStatement继承自Statement、CallableStatement继承自PreparedStatement。 3. Statement接口提供了执行语句和获取结果的基本方法࿱…...
济南网站建设直播/seo网站排名优化公司
理解 C# 项目 csproj 文件格式的本质和编译流程 2018年05月19日 07:58:23 walter lv 阅读数 1901更多 所属专栏: NuGet .NET 编译过程 版权声明:本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发…...
能发外链的网站/seo线上培训班
没有使用igraph库哦 因为我还没学小世界网络简介:1998年, Watts和Strogatz 提出了小世界网络这一概念,并建立了WS模型。实证结果表明,大多数的真实网络都具有小世界特性(较小的最短路径)和聚类特性(较大的聚类系数)。传统的规则最近邻耦合网络…...
wordpress使用置顶文章没用/网络平台的推广方法
PPT文件上呦限制编辑,不知道密码应该怎么去掉? 取消限制编辑在不知道密码的情况下,需要用到工具的帮助【PPT解密大师】快速找回密码_轻松移除使用限制-奥凯丰okfone 选择【解除限制】将PPT文件添加到软件中,点击一下【开始】就可…...
柬埔寨美女教你用母乳做奶茶原网站/考研培训班集训营
这车问题超级多。 1, 后视镜看不到人,因为太短了。 2,电池剩余电量不准。...
陕西手机网站建设公司/网络营销专业学什么
一、需求 1,用户端采集或者录入或者生成业务数据 2,将业务数据放入集合,按照业务需求,进行数据管理操作 3,将集合的数据放入数据库 难点:怎么遍历HashMap得到键和值 // 获取 所有的 entry对象 entrySetSet<Map.Entry<String,String&…...