【JUC基础】JUC入门基础
目录
- 什么是JUC
- 线程和进程
- 锁
- 传统的 synchronized
- Lock 锁
- Synchronized 与 Lock 的区别
- 生产者和消费者问题
- Synchronized 版
- Lock版
- Condition 的优势:精准通知和唤醒线程
- 8 锁现象
- 问题1:两个同步方法,先执行发短信还是打电话?
- 问题2:问题1基础上让发短信延迟 4s
- 问题三:换成一个普通方法结果?
- 问题四:如果使用的是两个对象,一个调用发短信,一个调用打电话,那么整个顺序是怎么样的呢?
- 问题五、六:如果我们把 synchronized 的方法加上 static 变成静态方法,那么顺序又是怎么样的呢?
- 问题七:如果使用一个静态同步方法、一个同步方法、一个对象调用顺序是什么?
- 问题八:如果我们使用一个静态同步方法、一个同步方法、两个对象调用顺序是什么?
什么是JUC
JUC 就是 java.util.concurrent
下面的类包,专门用于多线程的开发。
Lock:可重入锁、可重入读锁、可重入写锁
线程和进程
Java默认有几个线程?
答:2个线程。 main线程、GC线程
Java 真的可以开启线程吗?
答:开不了。Java 是没有权限去开启线程、操作硬件的,这是一个 native 的一个本地方法,它调用的底层的 C++ 代码。
// Thread类源码
public synchronized void start() {/*** This method is not invoked for the main method thread or "system"* group threads created/set up by the VM. Any new functionality added* to this method in the future may have to also be added to the VM.** A zero status value corresponds to state "NEW".*/if (threadStatus != 0)throw new IllegalThreadStateException();/* Notify the group that this thread is about to be started* so that it can be added to the group's list of threads* and the group's unstarted count can be decremented. */group.add(this);boolean started = false;try {start0();started = true;} finally {try {if (!started) {group.threadStartFailed(this);}} catch (Throwable ignore) {/* do nothing. If start0 threw a Throwable thenit will be passed up the call stack */}}}//这是一个C++底层,Java是没有权限操作底层硬件的private native void start0();
线程的状态有哪几种?
// Thread类源码
public enum State { //新生NEW,//运行RUNNABLE,//阻塞BLOCKED,//等待WAITING,//超时等待TIMED_WAITING,//终止TERMINATED;
}
并发:多线程操作同一个资源。CPU 只有一核,模拟出来多条线程。可以使用CPU快速交替,来模拟多线程。
并行:CPU多核,多个线程可以同时执行。 可以使用线程池。
获取CPU的核数:
// 获取CPU的核数
System.out.println(Runtime.getRuntime().availableProcessors());
wait / sleep:
- 1、来自不同的类 wait =>
Object
,sleep =>Thread
// 一般情况企业中使用休眠
import java.util.concurrent.TimeUnit;TimeUnit.DAYS.sleep(1); //休眠1天
TimeUnit.SECONDS.sleep(1); //休眠1s
- 2、关于锁的释放 wait 会释放锁,sleep不会释放锁
- 3、使用的范围是不同的 wait 必须在同步代码块中,sleep 可以在任何地方睡
- 4、是否需要捕获异常 sleep 必须要捕获异常,wait 也是需要捕获异常,notify 和 notifyAll 不需要捕获异常
锁
传统的 synchronized
public class test {public static void main(String[] args) {//并发:多线程操作同一个资源类,将资源类丢入线程中Ticket ticket = new Ticket();new Thread(()->{for (int i = 0; i < 40; i++) {ticket.sale();}},"A").start();new Thread(()->{for (int i = 0; i < 40; i++) {ticket.sale();}},"B").start();new Thread(()->{for (int i = 0; i < 40; i++) {ticket.sale();}},"C").start();}
}// 资源类 OOP 属性、方法
class Ticket {private int number = 30;//卖票的方式public synchronized void sale() {if (number > 0) {System.out.println(Thread.currentThread().getName() + "卖出了第" + (number--) + "张票剩余" + number + "张票");}}
}
Lock 锁
// ReentrantLock源码/*** Creates an instance of {@code ReentrantLock}.* This is equivalent to using {@code ReentrantLock(false)}.*/public ReentrantLock() {sync = new NonfairSync(); //非公平锁:十分不公平,可以插队;(默认为非公平锁)}/*** Creates an instance of {@code ReentrantLock} with the* given fairness policy.** @param fair {@code true} if this lock should use a fair ordering policy*/public ReentrantLock(boolean fair) {sync = fair ? new FairSync() : new NonfairSync(); //公平锁:十分公平,必须先来后到}
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class test {public static void main(String[] args) {Ticket2 ticket = new Ticket2();new Thread(() -> {for (int i = 0; i < 40; i++) {ticket.sale();}}, "A").start();new Thread(() -> {for (int i = 0; i < 40; i++) {ticket.sale();}}, "B").start();new Thread(() -> {for (int i = 0; i < 40; i++) {ticket.sale();}}, "C").start();}
}//lock三部曲
//1、 Lock lock=new ReentrantLock();
//2、 lock.lock() 加锁
//3、 finally=> 解锁:lock.unlock();
class Ticket2 {private int number = 30;// 创建锁Lock lock = new ReentrantLock();//卖票的方式public void sale() {lock.lock(); // 开启锁try {if (number > 0) {System.out.println(Thread.currentThread().getName() + "卖出了第" + (number--) + "张票剩余" + number + "张票");}} finally {lock.unlock(); // 关闭锁}}
}
Synchronized 与 Lock 的区别
- Synchronized 内置的 Java关键字,Lock是一个 Java 类。
- Synchronized 无法判断获取锁的状态,Lock可以判断。
- Synchronized 会自动释放锁,Lock 必须要手动加锁和手动释放锁,可能会遇到死锁。
- Synchronized 线程1(获得锁->阻塞)、线程2(等待);Lock 就不一定会一直等待下去,Lock 会有一个trylock 去尝试获取锁,不会造成长久的等待。
- Synchronized 是可重入锁,不可以中断的,非公平的;Lock是可重入的,可以判断锁,可以自己设置公平锁和非公平锁。
- Synchronized 适合锁少量的代码同步问题,Lock适合锁大量的同步代码。
生产者和消费者问题
Synchronized 版
- Synchronized、wait、notify
/*** 线程之间的通信问题:生产者和消费者问题! 等待唤醒,通知唤醒* 线程交替执行 A B 操作同一个变量 num = 0* A num+1* B num-1*/
//顺序:判断待->业务->通知
public class test {public static void main(String[] args) {Data data = new Data();new Thread(() -> {for (int i = 0; i < 10; i++) {try {data.increment();} catch (InterruptedException e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {data.decrement();} catch (InterruptedException e) {e.printStackTrace();}}}, "B").start();}
}class Data {private int number = 0;//+1public synchronized void increment() throws InterruptedException {if (number != 0) {//等待this.wait();}number++;System.out.println(Thread.currentThread().getName() + "=>" + number);// 通知其他线程,我-1完毕了this.notifyAll();}//-1public synchronized void decrement() throws InterruptedException {if (number == 0) {//等待this.wait();}number--;System.out.println(Thread.currentThread().getName() + "=>" + number);// 通知其他线程,我-1完毕了this.notifyAll();}
}/*A=>1B=>0A=>1B=>0...
*/
俩个加俩个减 存在问题(虚假唤醒):
如果有四个线程,会出现虚假唤醒。
if 改为 while 即可,防止虚假唤醒。
结论:
就是用 if 判断的话,唤醒后线程会从 wait 之后的代码开始运行,但是不会重新判断if条件,直接继续运行 if 代码块之后的代码,而如果使用 while 的话,也会从 wait 之后的代码运行,但是唤醒后会重新判断循环条件,如果不成立再执行 while 代码块之后的代码块,成立的话继续 wait。这也就是为什么用 while 而不用if的原因了,因为线程被唤醒后,执行开始的地方是 wait 之后。
public class test {public static void main(String[] args) {Data data = new Data();new Thread(() -> {for (int i = 0; i < 10; i++) {try {data.increment();} catch (InterruptedException e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {data.decrement();} catch (InterruptedException e) {e.printStackTrace();}}}, "B").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {data.increment();} catch (InterruptedException e) {e.printStackTrace();}}}, "C").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {data.decrement();} catch (InterruptedException e) {e.printStackTrace();}}}, "D").start();}
}class Data {private int number = 0;//+1public synchronized void increment() throws InterruptedException {while (number != 0) {//等待this.wait();}number++;System.out.println(Thread.currentThread().getName() + "=>" + number);// 通知其他线程,我-1完毕了this.notifyAll();}//-1public synchronized void decrement() throws InterruptedException {while (number == 0) {//等待this.wait();}number--;System.out.println(Thread.currentThread().getName() + "=>" + number);// 通知其他线程,我-1完毕了this.notifyAll();}
}
Lock版
- Lock、await(Condition)、signal(Condition)
public class test {public static void main(String[] args) {Data2 data = new Data2();new Thread(() -> {for (int i = 0; i < 10; i++) {try {data.increment();} catch (InterruptedException e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {data.decrement();} catch (InterruptedException e) {e.printStackTrace();}}}, "B").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {data.increment();} catch (InterruptedException e) {e.printStackTrace();}}}, "C").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {data.decrement();} catch (InterruptedException e) {e.printStackTrace();}}}, "D").start();}
}class Data2 {private int num = 0;Lock lock = new ReentrantLock();Condition condition = lock.newCondition();// +1public void increment() throws InterruptedException {lock.lock();try {// 判断等待while (num != 0) {condition.await();}num++;System.out.println(Thread.currentThread().getName() + "=>" + num);// 通知其他线程 +1 执行完毕condition.signalAll();}finally {lock.unlock();}}// -1public void decrement() throws InterruptedException {lock.lock();try {// 判断等待while (num == 0) {condition.await();}num--;System.out.println(Thread.currentThread().getName() + "=>" + num);// 通知其他线程 +1 执行完毕condition.signalAll();}finally {lock.unlock();}}
}
Condition 的优势:精准通知和唤醒线程
要指定通知的下一个进行顺序,可以使用 Condition 来指定通知进程。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** Description:* A 执行完 调用B* B 执行完 调用C* C 执行完 调用A**/
public class test {public static void main(String[] args) {Data3 data3 = new Data3();new Thread(() -> {for (int i = 0; i < 10; i++) {data3.printA();}},"A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data3.printB();}},"B").start();new Thread(() -> {for (int i = 0; i < 10; i++) {data3.printC();}},"C").start();}
}class Data3 {private Lock lock = new ReentrantLock();private Condition condition1 = lock.newCondition();private Condition condition2 = lock.newCondition();private Condition condition3 = lock.newCondition();private int num = 1; // 实现1A 2B 3Cpublic void printA() {lock.lock();try {// 业务代码 判断 -> 执行 -> 通知while (num != 1) {condition1.await();}System.out.println(Thread.currentThread().getName() + "==> AAAA" );// 唤醒,唤醒指定的人Bnum = 2;condition2.signal();}catch (Exception e) {e.printStackTrace();}finally {lock.unlock();}}public void printB() {lock.lock();try {// 业务代码 判断 -> 执行 -> 通知while (num != 2) {condition2.await();}System.out.println(Thread.currentThread().getName() + "==> BBBB" );num = 3;condition3.signal();}catch (Exception e) {e.printStackTrace();}finally {lock.unlock();}}public void printC() {lock.lock();try {// 业务代码 判断 -> 执行 -> 通知while (num != 3) {condition3.await();}System.out.println(Thread.currentThread().getName() + "==> CCCC" );num = 1;condition1.signal();}catch (Exception e) {e.printStackTrace();}finally {lock.unlock();}}
}
/*
A==> AAAA
B==> BBBB
C==> CCCC
A==> AAAA
B==> BBBB
C==> CCCC
...
*/
8 锁现象
如何判断锁的是谁?锁会锁住:对象、Class
问题1:两个同步方法,先执行发短信还是打电话?
import java.util.concurrent.TimeUnit;public class test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();new Thread(() -> {phone.sendMs();}).start();TimeUnit.SECONDS.sleep(1);new Thread(() -> {phone.call();}).start();}
}class Phone {public synchronized void sendMs() {System.out.println("发短信");}public synchronized void call() {System.out.println("打电话");}
}//发短信
//打电话
问题2:问题1基础上让发短信延迟 4s
import java.util.concurrent.TimeUnit;public class test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();new Thread(() -> {try {phone.sendMs();} catch (InterruptedException e) {e.printStackTrace();}}).start();TimeUnit.SECONDS.sleep(1);new Thread(() -> {phone.call();}).start();}
}class Phone {public synchronized void sendMs() throws InterruptedException {TimeUnit.SECONDS.sleep(4);System.out.println("发短信");}public synchronized void call() {System.out.println("打电话");}
}//发短信
//打电话
问题一问题二说明并不是顺序执行,而是 synchronized 锁住的对象是方法的调用,对于两个方法用的是同一个锁,谁先拿到谁先执行,另外一个等待。
问题三:换成一个普通方法结果?
hello 是一个普通方法,不受 synchronized 锁的影响,不用等待锁的释放。
import java.util.concurrent.TimeUnit;public class test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();new Thread(() -> {try {phone.sendMs();} catch (InterruptedException e) {e.printStackTrace();}}).start();TimeUnit.SECONDS.sleep(1);new Thread(() -> {phone.hello();}).start();}
}class Phone {public synchronized void sendMs() throws InterruptedException {TimeUnit.SECONDS.sleep(4);System.out.println("发短信");}public synchronized void call() {System.out.println("打电话");}public void hello() {System.out.println("hello");}
}
//hello
//发短信
问题四:如果使用的是两个对象,一个调用发短信,一个调用打电话,那么整个顺序是怎么样的呢?
两个对象两把锁,不会出现等待的情况,发短信睡了4s,所以先执行打电话
import java.util.concurrent.TimeUnit;public class test {public static void main(String[] args) throws InterruptedException {Phone phone1 = new Phone();Phone phone2 = new Phone();new Thread(() -> {try {phone1.sendMs();} catch (InterruptedException e) {e.printStackTrace();}}).start();TimeUnit.SECONDS.sleep(1);new Thread(() -> {phone2.call();}).start();}
}class Phone {public synchronized void sendMs() throws InterruptedException {TimeUnit.SECONDS.sleep(4);System.out.println("发短信");}public synchronized void call() {System.out.println("打电话");}public void hello() {System.out.println("hello");}
}
//打电话
//发短信
问题五、六:如果我们把 synchronized 的方法加上 static 变成静态方法,那么顺序又是怎么样的呢?
static 静态方法来说,对于整个类 Class 来说只有一份,对于不同的对象使用的是同一份方法,相当于这个方法是属于类的,如果静态 static 方法使用 synchronized 锁定,那么这个 synchronized 锁会锁住整个对象,不管多少个对象,对于静态的锁都只有一把锁,谁先拿到这个锁就先执行,其他的进程都需要等待。
import java.util.concurrent.TimeUnit;public class test {public static void main(String[] args) throws InterruptedException {new Thread(() -> {try {Phone.sendMs();} catch (InterruptedException e) {e.printStackTrace();}}).start();TimeUnit.SECONDS.sleep(1);new Thread(() -> {Phone.call();}).start();}
}class Phone {public static synchronized void sendMs() throws InterruptedException {TimeUnit.SECONDS.sleep(4);System.out.println("发短信");}public static synchronized void call() {System.out.println("打电话");}
}
//发短信
//打电话
问题七:如果使用一个静态同步方法、一个同步方法、一个对象调用顺序是什么?
因为一个锁的是Class类的模板,一个锁的是对象的调用者。所以不存在等待,直接运行
import java.util.concurrent.TimeUnit;public class test {public static void main(String[] args) throws InterruptedException {Phone phone1 = new Phone();
// Phone phone2 = new Phone();new Thread(() -> {try {Phone.sendMs();} catch (InterruptedException e) {e.printStackTrace();}}).start();TimeUnit.SECONDS.sleep(1);new Thread(() -> {phone1.call();}).start();}
}class Phone {public static synchronized void sendMs() throws InterruptedException {TimeUnit.SECONDS.sleep(4);System.out.println("发短信");}public synchronized void call() {System.out.println("打电话");}public void hello() {System.out.println("hello");}
}
//打电话
//发短信
问题八:如果我们使用一个静态同步方法、一个同步方法、两个对象调用顺序是什么?
两把锁锁的不是同一个东西
import java.util.concurrent.TimeUnit;public class test {public static void main(String[] args) throws InterruptedException {Phone phone1 = new Phone();Phone phone2 = new Phone();new Thread(() -> {try {Phone.sendMs();} catch (InterruptedException e) {e.printStackTrace();}}).start();TimeUnit.SECONDS.sleep(1);new Thread(() -> {phone2.call();}).start();}
}class Phone {public static synchronized void sendMs() throws InterruptedException {TimeUnit.SECONDS.sleep(4);System.out.println("发短信");}public synchronized void call() {System.out.println("打电话");}public void hello() {System.out.println("hello");}
}
//打电话
//发短信
相关文章:
【JUC基础】JUC入门基础
目录 什么是JUC线程和进程锁传统的 synchronizedLock 锁Synchronized 与 Lock 的区别 生产者和消费者问题Synchronized 版Lock版Condition 的优势:精准通知和唤醒线程 8 锁现象问题1:两个同步方法,先执行发短信还是打电话?问题2&a…...
自然语言处理: 第十章GPT的API使用
理论基础 现在的以GPT为首的生成类模型,它拥有对话的能力,它会根据你输入的暗示(prompt)或者指令(instruct)生成对应的回答。所以,不同的输入会导致不同的输出(其实由于chatgpt最终生成的答案是beam_search 以及随机采样的机制,所…...
docker使用harbor进行镜像仓库管理演示以及部分报错解决
目录 一.安装harbor和docker-compose 1.下载 2.将该文件修改为这样,修改好自己的hostname和port,后文的用户和密码可以不改也可以改,用于登录 3.安装 二.修改daemon.json文件和/etc/hosts文件 三.使用powershell作windows端域名映射 四…...
【精算研究01/10】 计量经济学的性质和范围
一、说明 计量经济学是使用统计方法来发展理论或测试经济学或金融学中的现有假设。计量经济学依赖于回归模型和零假设检验等技术。计量经济学也可以用来预测未来的经济或金融趋势。 图片来源:https://marketbusinessnews.com 二、 计量经济之简介 计量经济学是对经济…...
【python知识】用 Tkinter实现“剪刀-石头-布”和“弹球游戏 ”
一、提要 Tkinter是一个Python内置模块,它提供了一个简单易用的界面来创建GUI。 在实现一些动态的画面、如游戏还是需要一些创新性思维的。在本文中,我们将使用 Tkinter 探索 Python GUI 编程。我们将介绍 Tkinter 的基础知识,并演示如何使用…...
Android 绘制之文字测量
drawText() 绘制文字 绘制进度条:paint.strokeCap Paint.CAP.RONUD 线条两边样式 设置文字字体:paint.typeFace Resources.Compat.getFont(context,font) 设置加粗 paint.isFakeBoldText 设置居中: paint.setTextAlign Paint.Align.CENTER //居中, 并不是真正的居中 往…...
基于AVR128单片机智能传送装置
一、系统方案 1、板载可变电阻(电位器)R29的电压作为处理器ATmega128的模数转换模块中单端ADC0的模拟信号输入(跳线JP13短接)。 2、调节电位器,将改变AD转换接口ADC0的模拟信号输入,由处理器完成ADC0的A/D转…...
Nexus私有仓库+IDEA配置远程推送
目录 一、docker安装nexus本地私服,Idea通过maven配置deploy本地jar包(简单) 二、docker push镜像到第三方nexus远程私服(shell命令操作) 三、springboot通过maven插件自动生成docker镜像并push到nexus私服…...
idea2023项目上传到gitee
1、按照gitee插件 File——>Settings plugins——>Marketplace下面搜索gitee,然后按照gitee插件 2、上传项目 VCS_——>Share Project on Gitee 如果第一次没登录的需要先登录,登录完后就可以上传了...
【golang】派生数据类型---指针 标识符、关键字等
1、指针 对比C/C中的指针,go语言中的指针显得极为简洁,只是简单的获取某个空间的地址 或者 根据指针变量中的内容 获取对应存储空间的内容等操作。 具体示例如下: go中使用指针需要注意的点: 可以通过指针改变它所指向的内存空…...
深度学习技术
深度学习是什么? 深度学习,英文名为Deep Learning,其实就是机器学习的一种高级形式。它的灵感来源于人脑神经网络的工作方式,是一种让机器可以自主地从数据中学习和提取特征的技术。你可以把它想象成一位小侦探,通过不…...
TCP/IP网络江湖——物理层护江山:网络安全的铁壁防线(物理层下篇:物理层与网络安全)
TCP/IP网络江湖——物理层护江山:网络安全的铁壁防线(物理层下篇:物理层与网络安全) 〇、引言一、物理层的隐私与保密1.1 加密技术的护盾1.2 安全传输协议的密约1.3 物理层的安全控制1.4 面对未知威胁的准备二、电磁干扰与抵御2.1 电磁干扰的威胁2.2 抗干扰技术的应用2.3 屏…...
python-数据可视化-使用API
使用Web应用程序编程接口 (API)自动请求网站的特定信息而不是整个网页,再对这些信息进行可视化 使用Web API Web API是网站的一部分,用于与使用具体URL请求特定信息的程序交互。这种请求称为API调用 。请求的数据将以易于处理的…...
窗口看门狗
从下往上看: 1. 时钟设置 RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);//使能独立看门狗时钟 WWDG_SetPrescaler(WWDG_Prescaler_8);//看门狗预分频器WWDG counter clock (PCLK1/4096)/8 2.设置窗口值 实际就是设置WWDG_CR的低七位值, 但是这个值要大于0x40(也就是…...
开发新能源的好处
风能无论是总装机容量还是新增装机容量,全球都保持着较快的发展速度,风能将迎来发展高峰。风电上网电价高于火电,期待价格理顺促进发展。生物质能有望在农业资源丰富的热带和亚热带普及,主要问题是降低制造成本,生物乙…...
error: can‘t find Rust compiler
操作系统 win11 pip install -r requirements.txt 报错如下 Using cached https://pypi.tuna.tsinghua.edu.cn/packages/56/fc/a3c13ded7b3057680c8ae95a9b6cc83e63657c38e0005c400a5d018a33a7/pyreadline3-3.4.1-py3-none-any.whl (95 kB) Building wheels for collected p…...
全面解析MES系统中的车间退料管理
一、车间退料管理的定义: 车间退料是指在生产过程中,将不合格或多余的物料、半成品或成品从车间环节返还到供应链的过程。车间退料管理则是指对这一退料过程进行规范化、系统化的管理和跟踪。 二、车间退料管理的流程: 1. 退料申请…...
探究finally代码块是否执行
情况一:try代码块正常执行,无异常,finally代码块无retrun; 代码演示 public class Test38 {public static void main(String[] args) {int foo foo();System.out.println("foo:" foo);}public static int foo() {tr…...
leetcode刷题(字符串相加、包含每个查询的最小区间、模拟行走机器人、环形子数组的最大和、满足不等式的最大值、四数之和、树中距离之和)
目录 1、字符串相加 2、包含每个查询的最小区间 3、模拟行走机器人 4、环形子数组的最大和 5、满足不等式的最大值 6、四数之和 7、 树中距离之和 1、字符串相加 class Solution:def addStrings(self, num1: str, num2: str) -> str:i len(num1) - 1 # num1的末…...
Grafana reporter定时报表踩坑记录
前言:本以为测试grafana reporter功能能很顺利,但按照网上大佬分享的记录进行操作,屡屡报错,不知是因为我的grafana部署在k8s中之前由低版本升级到高版本导致的,还是其他原因,在grafana中安装Grafana Image Renderer 一直报错。 Github地址:https://github.com/IzakMar…...
Flutter 状态管理引子
1、为了更好地了解状态管理,先看看什么是状态。 在类似Flutter这样的响应式编程框架中,我们可以认为U相关的开发就是对数据进行封装,将之转换为具体的U1布局或者组件。借用Flutter官网的一张图,可以把我们在第二部分做的所有开发…...
CFC编程入门_【10分钟学会】
什么是CFC: 【差不多10分钟全学会】 CFC是图形化编程, 跟单片机的连线一样, 唯一的区别:功能块右侧是【只能输出】引脚。 只有左侧引脚可以输入输出。 有哪些控件: 指针:用于拖动功能块。 控制点…...
golang无需创建新切片
在 Go 语言中,append(b, 0)[:len(b)] 是一种常见的用法,用于在切片 b 后追加一个元素,并返回旧切片的前 len(b) 个元素。 这种用法的目的是将一个新元素追加到切片中,并确保切片的长度保持不变。具体步骤如下: 1. ap…...
Django基础5——ORM中间程序
文章目录 一、基本了解二、ORM基本操作2.1 连接数据库2.1.1 使用sqlite数据库2.1.2 使用MySQL数据库 2.2 对数据库操作2.2.1 增(前端数据——>数据库)2.2.2 查(数据库——>前端展示)2.2.3 改(修改数据࿰…...
SpringAOP详解(上)
当需要在方法前后做一些操作就需要借助动态代理来实现 一、动态代理实现方法 1、jdk自带实现方式 jdk实现代理是被代理类实现接口的方式 public interface UserInterface {void test(); }public class UserService implements UserInterface {public void test() {System.o…...
C++ 存储类
存储类定义 C 程序中变量/函数的范围(可见性)和生命周期。这些说明符放置在它们所修饰的类型之前。下面列出 C 程序中可用的存储类: autoregisterstaticexternmutablethread_local (C11) 从 C 17 开始,auto 关键字不再是 C 存储…...
【教程分享】Docker搭建Zipkin,实现数据持久化到MySQL、ES
1 拉取镜像 指定版本,在git查看相应版本,参考: https://github.com/openzipkin/zipkin 如2.21.7 docker pull openzipkin/zipkin:2.21.7 2 启动 Zipkin默认端口为9411。启动时通过-e server.portxxxx设置指定端口 docker run --name zi…...
数据库——MySQL高性能优化规范
文章目录 数据库命令规范数据库基本设计规范1. 所有表必须使用 Innodb 存储引擎2. 数据库和表的字符集统一使用 UTF83. 所有表和字段都需要添加注释4. 尽量控制单表数据量的大小,建议控制在 500 万以内。5. 谨慎使用 MySQL 分区表6.尽量做到冷热数据分离,减小表的宽度7. 禁止在…...
openapi中job提交
openapi中job提交 简介创建job查看job查看job 的描述查看job 的日志 镜像地址: https://www.jianshu.com/p/fcb3094f8c48?v1693020692471 简介 这里使用微软OpenPAI, 在nvidia的GPU设备上进行job测试。 创建job protocolVersion: 2 name: lenet_gpu_pytorch112_…...
Spring Boot 整合 分布式搜索引擎 Elastic Search 实现 数据聚合
文章目录 ⛄引言一、数据聚合⛅简介⚡聚合的分类 二、DSL实现数据聚合⏰Bucket聚合⚡Metric聚合 三、RestAPI实现数据聚合⌚业务需求⏰业务代码实现 ✅效果图⛵小结 ⛄引言 本文参考黑马 分布式Elastic search Elasticsearch是一款非常强大的开源搜索引擎,具备非常…...
用什么软件做购物网站/太原网站关键词排名
在执行Hadoop的创建目录、写数据等情况,可能会出现该异常,而在读文件的时候却不会报错,这主要是由于系统的用户名不同导致的,由于我们进行实际开发的时候都是用Windows操作系统,而编译后的JAVA程序是部署在Linux上的。…...
甘孜网站建设/东莞网站推广软件
转载于:https://www.cnblogs.com/xiaobiaomei/p/9216717.html...
wordpress图片pin按钮/赵阳竞价培训
网络安全的定义: 网络安全(Cyber Security)是指网络系统的硬件、软件及其系统中的数据受到保护,不因偶然的或者恶意的原因而遭受到破坏、更改、泄露,系统连续可靠正常地运行,[网络服务](https://baike.bai…...
保定网站制作公司/线上营销渠道有哪些
由于6.22博主要学测,大半时间学文化课,近期刷题量&写题解的数量会急剧下降。 这题出得挺经典的,首先一眼最小割,考虑朴素的做法:与S联通表示白色,与T联通表示黑色,S向i连流量为w[i]的边&…...
做网站工作怀孕/百度用户服务中心人工24小时电话
转自百度百科 数据库防火墙 系统,串联部署在数据库服务器之前,解决数据库应用侧和运维侧两方面的问题,是一款基于 数据库 协议分析与控制技术的数据库安全防护系统。DBFirewall基于主动防御机制,实现数据库的访问行为控制、危险…...
杭州网站开发响应式/手机网站制作教程
木马检测技术旨在验证所设计或者制造的芯片是否感染了硬件木马。 目录 一、流片前检测 1.1 功能验证 1.2 电路设计分析 1.3 形式化验证 二、流片后检测 2.1 破坏性检测方法 2.2 非破坏性检测方法 2.2.1 非破坏性逆向工程 2.2.2 逻辑测试 2.2.3 侧信道分析 主要在两个…...