juc概述和Lock接口
目录
一、什么是JUC
1、JUC概述
2、进程与线程
3、线程的状态
4、wait/sleep 的区别
5、并发与并行
6、管程
7、用户线程和守护线程
二、Lock接口
1、Synchronized
使用synchronized实现售票案例
使用synchronized实现增减变量操作
2、什么是 Lock
买票例子使用lock实现
增减变量操作使用lock实现
3、newCondition
增减变量操作使用Condition实现
线程定制化执行
4、ReentrantLock
5、ReadWriteLock
一、什么是JUC
1、JUC概述
JUC 就是 java.util .concurrent 工具包的简称。这是一个处理线程的工具包,JDK 1.5 开始出现的。
2、进程与线程
3、线程的状态
public enum State {/*** Thread state for a thread which has not yet started.*/NEW, // 新建/*** Thread state for a runnable thread. A thread in the runnable* state is executing in the Java virtual machine but it may* be waiting for other resources from the operating system* such as processor.*/RUNNABLE, // 运行时/*** Thread state for a thread blocked waiting for a monitor lock.* A thread in the blocked state is waiting for a monitor lock* to enter a synchronized block/method or* reenter a synchronized block/method after calling* {@link Object#wait() Object.wait}.*/BLOCKED, // 阻塞/*** Thread state for a waiting thread.* A thread is in the waiting state due to calling one of the* following methods:* <ul>* <li>{@link Object#wait() Object.wait} with no timeout</li>* <li>{@link #join() Thread.join} with no timeout</li>* <li>{@link LockSupport#park() LockSupport.park}</li>* </ul>** <p>A thread in the waiting state is waiting for another thread to* perform a particular action.** For example, a thread that has called <tt>Object.wait()</tt>* on an object is waiting for another thread to call* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on* that object. A thread that has called <tt>Thread.join()</tt>* is waiting for a specified thread to terminate.*/WAITING, //等待/*** Thread state for a waiting thread with a specified waiting time.* A thread is in the timed waiting state due to calling one of* the following methods with a specified positive waiting time:* <ul>* <li>{@link #sleep Thread.sleep}</li>* <li>{@link Object#wait(long) Object.wait} with timeout</li>* <li>{@link #join(long) Thread.join} with timeout</li>* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>* </ul>*/TIMED_WAITING, // 过时不候/*** Thread state for a terminated thread.* The thread has completed execution.*/TERMINATED; //终结}
4、wait/sleep 的区别
5、并发与并行
并发:并发是指两个或多个事件在同一时间间隔发生。
- 例子:春运抢票 电商秒杀...
并行:并行是指两个或者多个事件在同一时刻发生。
- 例子:泡方便面,电水壶烧水,一边撕调料倒入桶中
6、管程
7、用户线程和守护线程
二、Lock接口
1、Synchronized
- 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
- 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
- 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
- 修改一个类,其作用的范围是 synchronized 后面括号括起来的部分,作用主的对象是这个类的所有对象
虽然可以使用 synchronized 来定义方法,但 synchronized 并不属于方法定义的一部分,因此,synchronized 关键字不能被继承。如果在父类中的某个方法使用了 synchronized 关键字,而在子类中覆盖了这个方法,在子类中的这个方法默认情况下并不是同步的,而必须显式地在子类的这个方法中加上synchronized 关键字才可以。当然,还可以在子类方法中调用父类中相应的方法,这样虽然子类中的方法不是同步的,但子类调用了父类的同步方法,因此,子类的方法也就相当于同步了。
使用synchronized实现售票案例
//第一步 创建资源类,定义属性和和操作方法
class Ticket {//票数private int number = 30;//操作方法:卖票public synchronized void sale() {//判断:是否有票if(number > 0) {System.out.println(Thread.currentThread().getName()+" : 卖出:"+(number--)+" 剩下:"+number);}}
}public class SaleTicket {//第二步 创建多个线程,调用资源类的操作方法public static void main(String[] args) {//创建Ticket对象Ticket ticket = new Ticket();//创建三个线程new Thread(new Runnable() {@Overridepublic void run() {//调用卖票方法for (int i = 0; i < 40; i++) {ticket.sale();}}},"AA").start();new Thread(new Runnable() {@Overridepublic void run() {for(int i = 0; i < 40; i ++) {ticket.sale();}}},"DD");new Thread(new Runnable() {@Overridepublic void run() {//调用卖票方法for (int i = 0; i < 40; i++) {ticket.sale();}}},"BB").start();new Thread(new Runnable() {@Overridepublic void run() {//调用卖票方法for (int i = 0; i < 40; i++) {ticket.sale();}}},"CC").start();}
}
使用synchronized实现增减变量操作
当变量为0是线程A、C将其+1,当变量为1时B、D线程将其-1
//第一步 创建资源类,定义属性和操作方法
class Share {//初始值private int number = 0;//+1的方法public synchronized void incr() throws InterruptedException {//第二步 判断 干活 通知while(number != 0) { //判断number值是否是0,如果不是0,等待this.wait(); //在哪里睡,就在哪里醒}//如果number值是0,就+1操作number++;System.out.println(Thread.currentThread().getName()+" :: "+number);//通知其他线程this.notifyAll();}//-1的方法public synchronized void decr() throws InterruptedException {//判断while(number != 1) {this.wait();}//干活number--;System.out.println(Thread.currentThread().getName()+" :: "+number);//通知其他线程this.notifyAll();}
}public class ThreadDemo1 {//第三步 创建多个线程,调用资源类的操作方法public static void main(String[] args) {Share share = new Share();//创建线程new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr(); //+1} catch (InterruptedException e) {e.printStackTrace();}}},"AA").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr(); //-1} catch (InterruptedException e) {e.printStackTrace();}}},"BB").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr(); //+1} catch (InterruptedException e) {e.printStackTrace();}}},"CC").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr(); //-1} catch (InterruptedException e) {e.printStackTrace();}}},"DD").start();}
}
如果一个代码块被 synchronized 修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况:
2、什么是 Lock
- Lock 不是 Java 语言内置的,synchronized 是 Java 语言的关键字,因此是内置特性。Lock 是一个类,通过这个类可以实现同步访问;
- Lock 和 synchronized 有一点非常大的不同,采用 synchronized 不需要用户去手动释放锁,当 synchronized 方法或者 synchronized 代码块执行完之后,系统会自动让线程释放对锁的占用;而 Lock 则必须要用户去手动释放锁,如果没有主动释放锁,就有可能导致出现死锁现象。
public interface Lock {void lock();void lockInterruptibly() throws InterruptedException;boolean tryLock();boolean tryLock(long time, TimeUnit unit) throws InterruptedException;void unlock();Condition newCondition();
}
lock.lock();try{//处理任务}catch(Exception ex){}finally{lock.unlock(); //释放锁}
买票例子使用lock实现
//第一步 创建资源类,定义属性和和操作方法
class LTicket {//票数量private int number = 30;//创建可重入锁private final ReentrantLock lock = new ReentrantLock(true);//卖票方法public void sale() {//上锁lock.lock();try {//判断是否有票if(number > 0) {System.out.println(Thread.currentThread().getName()+" :卖出"+(number--)+" 剩余:"+number);}} finally {//解锁lock.unlock();}}
}public class LSaleTicket {//第二步 创建多个线程,调用资源类的操作方法//创建三个线程public static void main(String[] args) {LTicket ticket = new LTicket();new Thread(()-> {for (int i = 0; i < 40; i++) {ticket.sale();}},"AA").start();new Thread(() -> {for(int i = 0; i < 40; i ++) {ticket.sale();}}, "DD");new Thread(()-> {for (int i = 0; i < 40; i++) {ticket.sale();}},"BB").start();new Thread(()-> {for (int i = 0; i < 40; i++) {ticket.sale();}},"CC").start();}
}
增减变量操作使用lock实现
//第一步 创建资源类,定义属性和操作方法
class Share {private int number = 0;//创建Lockprivate Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();//+1public void incr() throws InterruptedException {//上锁lock.lock();try {//判断while (number != 0) {condition.await();}//干活number++;System.out.println(Thread.currentThread().getName()+" :: "+number);//通知condition.signalAll();}finally {//解锁lock.unlock();}}//-1public void decr() throws InterruptedException {lock.lock();try {while(number != 1) {condition.await();}number--;System.out.println(Thread.currentThread().getName()+" :: "+number);condition.signalAll();}finally {lock.unlock();}}
}public class ThreadDemo2 {public static void main(String[] args) {Share share = new Share();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr();} catch (InterruptedException e) {e.printStackTrace();}}},"AA").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr();} catch (InterruptedException e) {e.printStackTrace();}}},"BB").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr();} catch (InterruptedException e) {e.printStackTrace();}}},"CC").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr();} catch (InterruptedException e) {e.printStackTrace();}}},"DD").start();}}
3、newCondition
注意:在调用 Condition 的 await()/signal()方法前,也需要线程持有相关的 Lock 锁,调用 await()后线程会释放这个锁,在 singal()调用后会从当前 Condition 对象的等待队列中,唤醒 一个线程,唤醒的线程尝试获得锁, 一旦获得锁成功就继续执行。
增减变量操作使用Condition实现
//第一步 创建资源类,定义属性和操作方法
class Share {private int number = 0;//创建Lockprivate Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();//+1public void incr() throws InterruptedException {//上锁lock.lock();try {//判断while (number != 0) {condition.await();}//干活number++;System.out.println(Thread.currentThread().getName()+" :: "+number);//通知condition.signalAll();}finally {//解锁lock.unlock();}}//-1public void decr() throws InterruptedException {lock.lock();try {while(number != 1) {condition.await();}number--;System.out.println(Thread.currentThread().getName()+" :: "+number);condition.signalAll();}finally {lock.unlock();}}
}public class ThreadDemo2 {public static void main(String[] args) {Share share = new Share();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr();} catch (InterruptedException e) {e.printStackTrace();}}},"AA").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr();} catch (InterruptedException e) {e.printStackTrace();}}},"BB").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.incr();} catch (InterruptedException e) {e.printStackTrace();}}},"CC").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {share.decr();} catch (InterruptedException e) {e.printStackTrace();}}},"DD").start();}}
线程定制化执行
让线程按顺序执行,例子:
当flag为1时,A线程打印五次;
当flag为2时,B线程打印十次;
当flag为3时,C线程打印十五次;
按顺序打印。
//第一步 创建资源类
class ShareResource {//定义标志位private int flag = 1; // 1 AA 2 BB 3 CC//创建Lock锁private Lock lock = new ReentrantLock();//创建三个conditionprivate Condition c1 = lock.newCondition();private Condition c2 = lock.newCondition();private Condition c3 = lock.newCondition();//打印5次,参数第几轮public void print5(int loop) throws InterruptedException {//上锁lock.lock();try {//判断while(flag != 1) {//等待c1.await();}//干活for (int i = 1; i <=5; i++) {System.out.println(Thread.currentThread().getName()+" :: "+i+" :轮数:"+loop);}//通知flag = 2; //修改标志位 2c2.signal(); //通知BB线程}finally {//释放锁lock.unlock();}}//打印10次,参数第几轮public void print10(int loop) throws InterruptedException {lock.lock();try {while(flag != 2) {c2.await();}for (int i = 1; i <=10; i++) {System.out.println(Thread.currentThread().getName()+" :: "+i+" :轮数:"+loop);}//修改标志位flag = 3;//通知CC线程c3.signal();}finally {lock.unlock();}}//打印15次,参数第几轮public void print15(int loop) throws InterruptedException {lock.lock();try {while(flag != 3) {c3.await();}for (int i = 1; i <=15; i++) {System.out.println(Thread.currentThread().getName()+" :: "+i+" :轮数:"+loop);}//修改标志位flag = 1;//通知AA线程c1.signal();}finally {lock.unlock();}}
}public class ThreadDemo3 {public static void main(String[] args) {ShareResource shareResource = new ShareResource();new Thread(()->{for (int i = 1; i <=10; i++) {try {shareResource.print5(i);} catch (InterruptedException e) {e.printStackTrace();}}},"AA").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {shareResource.print10(i);} catch (InterruptedException e) {e.printStackTrace();}}},"BB").start();new Thread(()->{for (int i = 1; i <=10; i++) {try {shareResource.print15(i);} catch (InterruptedException e) {e.printStackTrace();}}},"CC").start();}
}
4、ReentrantLock
public class Test {private ArrayList<Integer> arrayList = new ArrayList<Integer>();public static void main(String[] args) {final Test test = new Test();new Thread() {public void run() {test.insert(Thread.currentThread());};}.start();new Thread() {public void run() {test.insert(Thread.currentThread());};}.start();}public void insert(Thread thread) {ReentrantLock lock = new ReentrantLock(); //注意这个地方lock.lock();try {System.out.println(thread.getName() + "得到了锁");for (int i = 0; i < 5; i++) {arrayList.add(i);}} catch (Exception e) {
// TODO: handle exception} finally {System.out.println(thread.getName() + "释放了锁");lock.unlock();}}
}
5、ReadWriteLock
public interface ReadWriteLock {/*** Returns the lock used for reading.** @return the lock used for reading.*/Lock readLock();/*** Returns the lock used for writing.** @return the lock used for writing.*/Lock writeLock();
}
public class Test {private ReentrantReadWriteLock rwl = newReentrantReadWriteLock();public static void main(String[] args) {final Test test = new Test();new Thread() {public void run() {test.get(Thread.currentThread());};}.start();new Thread() {public void run() {test.get(Thread.currentThread());};}.start();}public synchronized void get(Thread thread) {long start = System.currentTimeMillis();while (System.currentTimeMillis() - start <= 1) {System.out.println(thread.getName() + "正在进行读操作");}System.out.println(thread.getName() + "读操作完毕");}
}
而改成用读写锁的话:
public class Test {private ReentrantReadWriteLock rwl = newReentrantReadWriteLock();public static void main(String[] args) {final Test test = new Test();new Thread() {public void run() {test.get(Thread.currentThread());};}.start();new Thread() {public void run() {test.get(Thread.currentThread());};}.start();}public void get(Thread thread) {rwl.readLock().lock();try {long start = System.currentTimeMillis();while (System.currentTimeMillis() - start <= 1) {System.out.println(thread.getName() + "正在进行读操作");}System.out.println(thread.getName() + "读操作完毕");} finally {rwl.readLock().unlock();}}
}
== 注意: ==• 如果有一个线程已经占用了读锁,则此时其他线程如果要申请写锁,则申请写锁的线程会一直等待释放读锁。• 如果有一个线程已经占用了写锁,则此时其他线程如果申请写锁或者读锁,则申请的线程会一直等待释放写锁。
Lock 和 synchronized 有以下几点不同:
- Lock 是一个接口,而 synchronized 是 Java 中的关键字,synchronized 是内置的语言实现;
- synchronized 在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而 Lock 在发生异常时,如果没有主动通过 unLock()去释放锁,则很可能造成死锁现象,因此使用 Lock 时需要在 finally 块中释放锁;
- Lock 可以让等待锁的线程响应中断,而 synchronized 却不行,使用synchronized 时,等待的线程会一直等待下去,不能够响应中断;
- 通过 Lock 可以知道有没有成功获取锁,而synchronized 却无法办到。
- Lock 可以提高多个线程进行读操作的效率。
在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时 Lock 的性能要远远优于synchronized。
相关文章:
juc概述和Lock接口
目录 一、什么是JUC 1、JUC概述 2、进程与线程 3、线程的状态 4、wait/sleep 的区别 5、并发与并行 6、管程 7、用户线程和守护线程 二、Lock接口 1、Synchronized 使用synchronized实现售票案例 使用synchronized实现增减变量操作 2、什么是 Lock 买票例子使用lo…...
图像降采样的计算原理:F.interpolate INTER_AREA
一、F.interpolate——数组采样操作 torch.nn.functional.interpolate(input, size=None, scale_factor=None, mode=nearest, align_corners=None, recompute_scale_factor=None) 功能:利用插值方法,对输入的张量数组进行上\下采样操作,换句话说就是科学合理地改变数组的尺…...
云上的甜蜜早安:腾讯云云函数助力PHP打造女友专属每日推送
用腾讯云的云函数做一个微信公众号早安,每天定时发送早安给你的女朋友! 1.首先我们登录腾讯云,在搜索栏搜索云函数 2.进入云函数,点击立即体验 3.这里我们选择 按照步骤选择 php 4.再就是配置页面,这里我们只需要配…...
Javaweb基础学习(3)
Javaweb基础学习 web核心介绍一、HTTP1.1 HTTP介绍1.2、HTTP请求数据格式1.3、HTTP响应数据格式 二、Tomcat2.1 简介2.2 基本使用2.3 Tomcat配置2.4 Tomcat部署项目2.5 Web项目结构2.6 创建Maven Web项目 三、Servlet3.1、Servlet简介&快速入门3.2 创建Servlet步骤3.3 Serv…...
使用在 Web 浏览器中运行的 VSCode 实现 ROS2 测程法
一、说明 Hadabot是软件工程师学习ROS2和机器人技术的机器人套件。我们距离Hadabot套件的测试版还有一周左右的时间。我们将在本文末尾披露有关如何注册的更多信息。 新的Hadabot套件完全支持ROS2。除了硬件套件外,Hadabot软件环境将主要基于Web浏览器,以…...
快速学习GO语言总结
备注:本博客将自己初步学习GO的总结进行分享,希望大家通过本博客可以在短时间内快速掌握GO的基本程序编码能力,如有错误请留言指正,谢谢! 一、初步了解Go语言 (一)Go语言诞生的主要问题和目标…...
尚硅谷宋红康MySQL笔记 10-18
是记录,我不会记录的特别详细 第10章 创建和管理表 标识符命名规则 数据库名、表名不得超过30个字符,变量名限制为29个只能包含 A–Z, a–z, 0–9, _共63个字符数据库名、表名、字段名等对象名中间不要包含空格同一个MySQL软件中,数据库不能…...
Java 面试题--SpringBoot篇
一、什么是 SpringBoot? Spring Boot 是 Spring 开源组织下的子项目, 是 Spring 组件一站式解决方案,主要是简化 了使用 Spring 的难度,简省了繁重 xml 的配 置,提供了各种启动器,在运行过程中自定 配置,&a…...
GitKraken 详细图文教程
前言 写这篇文章的原因是组内的产品和美术同学,开始参与到git工作流中,但是网上又没有找到一个比较详细的使用教程,所以干脆就自己写了一个[doge]。文章的内容比较基础,介绍了Git内的一些基础概念和基本操作,适合零基…...
ubuntu20.04 root用户下使用中文输入法——root用户pycharm无法用中文输入法问题
因为一些众所不周知的bug,我的pycharm使用apt或者snap安装都不行了,官网下了“绿色版”,运行pycharm.sh也运行不起来,有个java相关环境报错,jre和jdk都装了,还是有点问题,最后尝试发现可以用roo…...
FastDFS与Nginx结合搭建文件服务器,并实现公网访问【内网穿透】
文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…...
嵌入式蓝海变红海?其实是大浪淘沙!
嵌入式是当下热门的职业方向之一,吸引了众多求职者的目光。然而,有人担心大家一拥而上,导致嵌入式就业竞争激烈,找工作难度大。其实,嵌入式行业的竞争并非无法逾越的天堑,也远远没有从蓝海变成红海…...
【附安装包】Solid Edge2023安装教程最强CAD选择
软件下载 软件:Solid Edge版本:2023语言:简体中文大小:3.85G安装环境:Win11/Win10/Win8/Win7硬件要求:CPU2.0GHz 内存4G(或更高)下载通道①百度网盘丨64位下载链接:https://pan.bai…...
494. 目标和
494. 目标和 原题链接:完成情况:解题思路:数组回溯法动态规划 参考代码:数组回溯法__494目标和__动态规划 经验吸取 原题链接: 494. 目标和 https://leetcode.cn/problems/target-sum/description/ 完成情况&#…...
C++学习笔记总结练习:C++编译过程详解
编译和链接的过程 0 概述 程序要运行起来,必须要经过四个步骤:预处理、编译、汇编和链接。接下来通过几个简单的例子来详细讲解一下这些过程。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFwSfKYp-1692237034055)(imag…...
嵌入式设备应用开发(qt界面开发)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 linux界面开发有很多的方案可以选。比如说lvgl、minigui、ftk之类的。但是,这么多年来,一直屹立不倒的还是qt。相比较其他几种方案,qt支持多个平台,这里面就包括了linux平台。此…...
pytest结合Excel实现接口自动化
前言 我们先来回顾下之前篇章“pytest通过parametrize方法实现数据驱动实战”,主要是通过yaml文件来读取测试用例。而我们用Excel文件存放测试用例又有什么区别呢? 毫无疑问,Pytest自动化测试框架也能读取Excel文件实现数据驱动。 还记得之…...
【LLM数据篇】预训练数据集+指令生成sft数据集
note 在《Aligning Large Language Models with Human: A Survey》综述中对LLM数据分类为典型的人工标注数据、self-instruct数据集等优秀的开源sft数据集:alpaca_data、belle、千言数据集、firefly、moss-003-sft-data多轮对话数据集等 文章目录 note构造指令实例…...
WebDAV之π-Disk派盘 + 一羽记帐
一羽记帐是一款真正让你体验3S极速记账的轻量级APP。针对个人记账,没有花哨冗余的功能。界面美丽、无广告、极速启动、功能全面。一羽记帐功能涵括广,基本可以满足90%人的记账需求。完全无侵入、百分百无广告,无需担心数据安全,所有的操作都不经过任何第三方。 π-Disk派盘…...
ChatGPT:记一次超复杂的KVM桌面系统连接问答记录
KVM切换器可以使多台电脑共用键盘,显示器,鼠标,当电脑很多,显示器也是分为主从,需要共用键盘鼠标和音响设备,而买KVM切换器只有2个通道4进2出不满足需求时,就要组合多个KVM使用,大…...
python-docx把dataframe表格添加到word文件中
python-docx把dataframe表格添加到word文件中思路较为简单: 先把dataframe格式转变为table新建一个段落:document.add_paragraph()把table添加到这个段落下方 效果图 示例代码 from docx import Document, oxml import pandas as pd import numpy as …...
Web AP—BOM 浏览器对象模型
代码下载 BOM BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window。 BOM 由一系列相关的对象构成,并且每个对象都提供了很多方法与属性。 BOM 缺乏标…...
Flink分流,合流,状态,checkpoint和精准一次笔记
第8章 分流 1.使用侧输出流 2.合流 2.1 union :使用 ProcessFunction 处理合流后的数据 2.2 Connect : 两条流的格式可以不一样, map操作使用CoMapFunction,process 传入:CoProcessFunction 2.2 BroadcastConnectedSt…...
c# 实现sql查询DataTable数据集 对接SqlSugar ORM
有时候对于已经查询到的数据集,想要进行二次筛选或者查询,还得再查一遍数据库 或者其他的一些逻辑处理不太方便,就想着为什么不能直接使用sql来查询DataTable呢? 搜索全网没找到可用方案,所以自己实现了一个。 主要…...
记一次布尔盲注漏洞的挖掘与分析
在上篇文章记一次由于整型参数错误导致的任意文件上传的漏洞成因的分析过程中,发现menu_id貌似是存在注入的。 public function upload() {$menu_id $this->post(menu_id);if ($id) {$where "id {$id}";if ($menu_id) {$where . " and menu_id…...
C++11 新特性 ---- noexcept
1. 异常 异常通常用于处理逻辑上可能发生的错误 在C98中,提供了一套完善的异常处理机制,直接在程序中将各种类型的异常抛出,从而强制终止程序的运行。 1.1 基本语法 当函数抛出异常时,程序会停止执行,并显示异常信息…...
《Linux运维总结:Centos7.6之OpenSSH7.4p1升级版本至9.4p1》
Centos通过yum升级OpenSSH 在官方支持更新的CentOS版本,如果出现漏洞,都会通过更新版本来修复漏洞。这时候直接使用yum update就可以升级版本。 yum -y update openssh 但是,CentOS更新需要有一段时间,不能在漏洞刚出来的时候就有…...
七夕节日表白:七大网页风格与其适用人群
🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…...
通达信指标公式16:使用BARSLAST函数写一个指标回测的思路
★★★★★博文原创不易,我的博文不需要打赏,也不需要知识付费,可以白嫖学习小技巧,喜欢的老铁可以多多帮忙点赞,小红牛在此表示感谢,就是对作者的最大支持。愿与诸君共勉,悟道于股市★★★★★…...
Jenkins自动化部署Vue项目
1、新建item,选择 Freestyle project 2、源码管理选择git,输入git仓库地址和授权账号,并指明要部署的分支 3、构建选择 Execute shell,输入vue项目打包命令 命令示例: source /etc/profile node -v npm config set re…...
网站的按钮怎么做/app制作
最大公约数和最小公倍数 辗转相除法求最大公约数gcd,然后lcm a * b / gcd 。 #include <iostream> using namespace std;long long gcd(long long a, long long b) {if (b 0)return a;return gcd(b, a%b); }long long lcm(long long a, long long b) {retu…...
天河区住房和建设水务局官方网站/高明搜索seo
前不久,也就是2016年3月底,VMware发布了最新的桌面虚拟化产品Horizon 7,该版本引入了全新的Blast桌面连接协议,改进了带宽占用,提高了性能,同时引入了革命性的“即时克隆”桌面池,使得虚拟机的创…...
微网站制作需要多少钱/百度广告费用
CentOS 5.4 pptp freeradius2 mysql daloradius 完美整合(图文并茂)转载于:https://blog.51cto.com/leekwen/1239280...
家居seo整站优化方案/推广策划方案怎么写
Kubemetes提供了一组默认的ClusterRole和ClusterRoleBinding,每次API服务器启动时都会更新它们。这保证了在你错误地删除角色和绑定,或者Kubernetes的新版本使用了不同的集群角色和绑定配置时, 所有的默认角色和绑定都会被重新创建。 view、 …...
免费做网站tk/方象科技的企业愿景
简介 如果需要远程访问计算机并启用了 Secure Shell (SSH) 连接,黑客就会尝试突破您的防线并控制您的计算机,您必须接受这个事实。尽管不能保证计算机不会被 “黑客” 占领,但是一些简单的解决方案有助于保护 SSH,可以让攻击困难…...
武汉网站快照优化公司/企业品牌类网站有哪些
如果所有diy都不想要了,手动清空_common_block、_common_diy_data与_common_template_block表,然后删除\data\diy\下的所有子文件夹,保证你以前所有的diy干干净净,就像从未diy过的disciz x。以后删除diy的内容时,老老实…...