当前位置: 首页 > news >正文

JAVA基础-线程(Thread)、多线程(Multi-threaded)

1、知识铺垫

        要想了解什么是线程,首先要搞明白线程与进程的区别,并行与并发的区别

1.1 线程与进程

        进程:是指⼀个内存中运⾏的应⽤程序,每个进程都有⼀个独⽴的内存空间,⼀个应⽤程序可以同时运⾏多个进程;进程也是程序的⼀次执⾏过程,是系统运⾏程序的基本单位;系统运⾏⼀个程序即是 ⼀个进程从创建、运⾏到消亡的过程。
        线程:线程是进程中的⼀个执⾏单元,负责当前进程中程序的执⾏,⼀个进程中⾄少有⼀个线程。⼀个进程中是可以有多个线程的,这个应⽤程序也可以称之为多线程程序。
        简⽽⾔之:⼀个程序运⾏后⾄少有⼀个进程,⼀个进程中可以包含多个线程

1.2 并行与并发

并发:指两个或多个事件在同⼀个时间段内发⽣。
并⾏:指两个或多个事件在同⼀时刻发⽣(同时发⽣)。

        在操作系统中,安装了多个程序,并发指的是在⼀段时间内宏观上有多个程序同时运⾏,这在单 CPU 系统中,每⼀时刻只能有⼀道程序执⾏,即微观上这些程序是分时的交替运⾏,只不过是给⼈的感觉是同时运 ⾏,那是因为分时交替运⾏的时间是⾮常短的。

        ⽽在多个 CPU 系统中,则这些可以并发执⾏的程序便可以分配到多个处理器上( CPU ),实现多任务并⾏ 执⾏,即利⽤每个处理器来处理⼀个可以并发执⾏的程序,这样多个程序便可以同时执⾏。⽬前电脑市场 上说的多核 CPU ,便是多核处理器,核 越多,并⾏处理的程序越多,能⼤⼤的提⾼电脑运⾏的效率。

注意:单核处理器的计算机肯定是不能并⾏的处理多个任务的,只能是多个任务在单个 CPU 上并发运 ⾏。同理 , 线程也是⼀样的,从宏观⻆度上理解线程是并⾏运⾏的,但是从微观⻆度上分析却是串⾏ 运⾏的,即⼀个线程⼀个线程的去运⾏,当系统只有⼀个 CPU 时,线程会以某种顺序执⾏多个线程, 我们把这种情况称之为线程调度。

2、线程

2.1 创建线程的方式

  1. 继承Thread类并重写run()方法。
  2. 实现Runnable接口并重写run()方法。将Runnable实例作为Thread类的构造函数参数传递并启动线程。
  3. 实现Callable接口并重写call()方法。使用ExecutorService的submit()方法提交Callable任务,并通过Future对象获取返回值。
  4. 线程池创建

2.1.1 Runnable 和 Callable 的区别

Runnable 接口 run 方法无返回值,且无法捕获处理异常;

Callable 接口 call 方法有返回值,支持泛型, 可以获取异常信息

2.2 线程的状态 

NEW(新建)

RUNNABLE(运行)

BLOCKED(阻塞)

WAITING(等待)

TIME_WAITING(超时等待)

TERMINATED (终止)

2.3 线程的相关方法

  1. 线程等待(wait):会释放对象的锁进入waiting
  2. 线程睡眠(sleep):不会释放当前占有的锁(进入time-waiting)
  3. 线程让步(yield):与其他线程一起重新竞争CPU 时间片
  4. 线程中断(interrupt):线程在合适的时候中断
  5. Join 等待其他线程终止:则当前线程转为阻塞状态,会到另一个线程结束,当前线程再由阻塞状态变为就绪状态,等待 cpu 的宠幸
  6. .线程唤醒(notify)

2.3.1 wait()和 sleep()的区别

wait()sleep()
来自的类Object 类Thread 类
锁的释放在等待的过程中会释放锁在等待的过程中不会释放锁
使用范围必须在同步代码块中使用可以在任何地方使用

2.3.2 run()与start()方法

run() 方法是线程的执行体,线程启动后会执行 run() 方法中的代码,当 run() 方法执行完毕后

start() 方法用于启动一个新线程,它会创建一个新的线程,并在新的线程中执行 run() 方法中的代码。在调用 start() 方法的时候,JVM 会为新的线程分配资源,并执行该线程中的 run() 方法。

2.4 ThreadLocal(token、localdate、traceid)

        线程级别的存储工具,是一个线程本地变量,为每一个线程都创建一个私有的变量,每个线程只能获取到自己的变量,从而避免了线程安全问题,是一个线程级别的哈希表,用于存储每个线程的变量。ThreadLocalMap 以 ThreadLocal 对象作为 key,以变量值作为 value,每个线程都可以通过 ThreadLocalMap 获取自己的变量

2.4.1 ThreadLocal使用场景

  1. 需要保存线程的上下文信息,例如 用户信息,通过token解析出来的用户id等
  2. 需要对线程的局部变量进行隔离,避免线程安全问题; LocalDate LocalDateTime
  3. 需要在跨类跨方法使用同一个变量,同时又不希望使用全局变量的情况;
  4. 需要避免传递参数的繁琐,例如在 Spring 框架中使用的事务管理。

2.4.2 ThreadLocal注意事项

每次使用后都要使用remove()删除数据

不不然会造成内存泄露,进而造成内存溢出

2.4.5 内存泄漏和内存溢出

  1. 内存泄漏:对象使用之后,并没有释放,内存一直被占用,业务代码频繁执行之后,大量这样的对象不被回收,造成可用的内存空间越来越少,最终造成内存溢出。通俗点讲就是 不用的垃圾没有丢掉.
  2. 内存溢出:当创建的对象的大小大于可用的内存容量大小。

3 、多线程

3.1 多线程的基本知识

        多线程是计算机多任务处理的一种方式,它允许单个程序中同时运行多个任务。在多线程模型中,每个线程代表执行流程中的一个独立的任务,它们可以并行处理以提高效率。

        在操作系统中,进程是资源分配的基本单位,而线程是程序执行的最小单位。一个进程可以包含多个线程,每个线程执行不同的任务。多线程的出现,使得程序可以同时执行多个任务,例如,一个文本编辑器可以在保存文件的同时继续接受用户的输入。

        多线程单线程相比,最大的优势在于可以并行处理任务,提高资源利用率和程序响应速度。例如,一个网络服务器可以同时处理多个客户端请求,而不是一次处理一个。

4、线程池

        线程池(ThreadPool)是一种基于池化思想管理和使用线程的机制:它是将多个线程预先存储在一个“池子”内,当有任务出现时可以避免重新创建和销毁线程所带来性能开销,只需要从“池子”内取出相应的线程执行对应的任务即可

4.1 线程池的工作原理

当一个任务提交至线程池之后,

1. 线程池首先判断核心线程池里的线程是否已经满了。如果不是,则创建一个新的工作线程来执行任务。否则进入 2.

2. 判断工作队列是否已经满了,倘若还没有满,将任务放入队列。否则进入 3.

3. 判断线程池里的线程是否都在执行任务。如果不是,则创建一个新的工作线程来执行。

如果线程池满了,则交给饱和策略来处理任务。

4.1.2 线程池主要优点

  • 降低资源消耗(复用线程,减少线程频繁新建、销毁等带来的开销)
  • 提高响应速度
  • 提高线程的可管理性

4.1.2 阿里巴巴不推荐使用JDK自带线程池的原因

        同时,阿里巴巴在其《Java开发手册》中也强制规定:线程资源必须通过线程池提供,不允许在应用中自行显式创建线程。

阿里巴巴开发手册为什么禁止使用 Executors 去创建线程池,原因就是 newFixedThreadPool() 和 newSingleThreadExecutor()两个方法允许请求的最大队列长度是 Integer.MAX_VALUE ,可能会出现任务堆积,出现OOM。newCachedThreadPool()允许创建的线程数量为 Integer.MAX_VALUE,可能会创建大量的线程,导致发生OOM。它建议使用ThreadPoolExecutor方式去创建线程池,通过上面的分析我们也知道了其实Executors 三种创建线程池的方式最终就是通过ThreadPoolExecutor来创建的,只不过有些参数我们无法控制,如果通过ThreadPoolExecutor的构造器去创建,我们就可以根据实际需求控制线程池需要的任何参数,避免发生OOM异常。

4.2 使用线程池-线程池的创建方式

线程池的创建方法总共有 7 种,但总体来说可分为 2 类:

通过 ThreadPoolExecutor 创建的线程池
通过 Executors 创建的线程池

线程池的创建方式总共包含以下 7 种(其中 6 种是通过 Executors 创建的,1 种是通过 ThreadPoolExecutor 创建的):

  1. Executors.newFixedThreadPool():创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待;
  2. Executors.newCachedThreadPool():创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收多余的线程,若线程数不够,则新建线程;
  3. Executors.newScheduledThreadPool():创建一个可以执行延迟任务的线程池;
  4. Executors.newSingleThreadExecutor():创建单个线程数的线程池,它可以保证先进先出的执行顺序;
  5. Executors.newSingleThreadScheduledExecutor():创建一个单线程的可以执行延迟任务的线程池;
  6. Executors.newWorkStealingPool():创建一个抢占式执行的线程池(任务执行顺序不确定)JDK 1.8 添加
  7. ThreadPoolExecutor:最原始的创建线程池的方式,它包含了 7 个参数可供设置

        单线程池的意义: 虽然 newSingleThreadExecutor 和 newSingleThreadScheduledExecutor 是单线程池,但提供了工作队列,生命周期管理,工作线程维护等功能。

4.3 线程池的参数

参数代表的含义如下:

  • corePoolSize核心线程数,线程池中始终存活的线程数。
  • maximumPoolSize最大线程数,线程池中允许的最大线程数,当线程池的任务队列满了之后可以创建的最大线程数。
  • keepAliveTime最大线程数可以存活的时间,当线程中没有任务执行时,最大线程就会销毁一部分,最终保持核心线程数量的线程。

unit:单位是和参数 3 存活时间配合使用的,合在一起用于设定线程的存活时间。参数 keepAliveTime 的时间单位有以下 7 种可选:

  1. TimeUnit.DAYS:天
  2. TimeUnit.HOURS:小时
  3. TimeUnit.MINUTES:分
  4. TimeUnit.SECONDS:秒
  5. TimeUnit.MILLISECONDS:毫秒
  6. TimeUnit.MICROSECONDS:微妙
  7. TimeUnit.NANOSECONDS:纳秒
  • workQueue一个阻塞队列,用来存储线程池等待执行的任务,均为线程安全。

        它一般分为直接提交队列、有界任务队列、无界任务队列、优先任务队列几种,包含以下 7 种类型:

  1. ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列。
  2. LinkedBlockingQueue:一个由链表结构组成的有界阻塞队列。
  3. SynchronousQueue:一个不存储元素的阻塞队列,即直接提交给线程不保持它们。
  4. PriorityBlockingQueue:一个支持优先级排序的无界阻塞队列。
  5. DelayQueue:一个使用优先级队列实现的无界阻塞队列,只有在延迟期满时才能从中提取元素
  6. LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法。
  7. LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

        较常用的是 LinkedBlockingQueue 和 Synchronous,线程池的排队策略与 BlockingQueue 有关

threadFactory线程工厂,主要用来创建线程。

handler拒绝策略,拒绝处理任务时的策略,系统提供了 4 种可选:

  1. AbortPolicy中止策略默认):拒绝并抛出异常。
  2. CallerRunsPolicy调用者运行策略:使用当前调用的线程来执行此任务。
  3. DiscardOldestPolicy丢弃最旧任务策略:抛弃队列头部(最旧)的一个任务,并执行当前任务。
  4. DiscardPolicy丢弃策略:忽略并抛弃当前任务。

 4.4 线程池的状态

1. 初始状态:线程池被创建时,里面并没有任何线程。此时线程池的状态为初始状态。

2. 运行状态:当向线程池中提交任务后,线程池中的线程开始执行任务,此时线程池的状态为运行状态。

3. 阻塞状态:当线程池中的任务队列已满,无法再接受新的任务时,线程池会进入阻塞状态,等待任务队列中的任务被执行完毕后再接受新的任务。

4. 关闭状态:当调用线程池的shutdown()方法时,线程池会进入关闭状态,此时线程池不再接受新的任务,但会执行任务队列中的任务。

5. 停止状态:当调用线程池的shutdownNow()方法时,线程池会进入停止状态,此时线程池不再接受新的任务,并且会中断正在执行的任务。

6. 终止状态:当线程池中所有的任务都执行完毕后,线程池会进入终止状态,此时线程池中不再有任何线程。

4.4.1 shutdownNow与shutdown的区别

1、shutdownNow 首先将线程池的状态设置为 STOP,然后尝试停止所有的正在执行和未执行任务的线程,并返回等待执行任务的列表;

2、shutdown 只是将线程池的状态设置为 SHUTDOWN 状态,然后中断所有没有正在执行任务的线程,继续执行正在执行的任务,直到任务结束.

5 、线程死锁 

5.1 死锁

        线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法继续执行

5.1.1 死锁的产生的条件(4者缺一不可)

  1. 互斥条件:一个资源一次只能被一个线程持有,如果其他线程想要获取该资源,就必须等待该线程释放该资源。
  2. 保持条件:一个线程请求资源时,如果已经持有了其他资源,就可以保持对这些资源的控制,直到满足所有资源的要求才释放
  3. 不剥夺条件:已经分配的资源不能被其他线程剥夺,只能由持有资源的线程释放
  4. 环路等待条件:个线程形成一种循环等待的关系,每个线程都在等待其他线程所持有的资源,从而导致死锁的产生。

5.1.2 如何避免死锁

避免死锁

  1. 尽量避免使用多个锁
  2. 减少锁的粒度:确保同步代码块的执行时间尽可能短,这样可以减少线程等待时间,
  3. 使用尝试锁:通过 ReentrantLock.tryLock() 方法可以尝试获取锁
  4. 避免嵌套锁

6、Synchronized同步锁

        会使用对象的内置锁(也称为监视器锁)来实现同步,每个对象都有一把内置锁,当一个线程访问一个同步代码块时,它会尝试获取这个锁,如果锁被其他线程持有,则该线程将被阻塞,直到锁被释放

  1. 互斥性一个线程拿锁,其他线程不能拿锁
  2. 可重入性同一个线程可以多次获取同步锁
  3. 独占性一个线程获得了对象的锁,则其他线程必须等待该线程释放锁之后才能获取锁。
  4. 缺点:非公平锁

6.2 synchronized静态方法和非静态方法的区别

  1. 当 synchronized 修饰非静态方法,它实际上是对调用该方法的对象实例进行加锁。这意味着如果有多个线程尝试访问同一个对象实例的不同 synchronized 非静态方法,它们将被串行执行,因为这些线程需要获取同一个对象锁。
  2. synchronized 修饰静态方法时:锁定的是类的Class对象,这意味着无论哪个线程访问该类的任何静态同步方法,都需要获取这个类的锁。因此,即使是不同的对象实例,只要它们调用的是同一个类的静态同步方法,这些调用也必须排队执行。

6.3 Synchronized与lock的区别

区别

Synchronized与lock

Lock(reentrantlock)

类型

关键字

接口

加锁方式

隐藏的加锁

显示的加锁

作用域

作用于方法上面

只能用于方法块上面

底层

对象内置锁

AQS(AbstractQueuedSynchronizer 抽象队列同步器)

锁类型

非公平锁

可选择非公平或公平锁

6.4 锁的升级 

6.4.1 基本概念

无锁 用户-> 偏向锁用户 -> 轻量级锁用户端 -> 重量级锁

        这是Java中针对synchronized锁的一种优化策略,它描述了锁状态可能经历的四个阶段,但并不是所有Java虚拟机都实现了这四个阶段,特别是偏向锁和轻量级锁的实现可能因JVM版本而异。

        对象刚创建是无锁状态,当第一个线程访问同步代码块时,升级为偏向锁,当第二个线程进来的时候,第二个线程会其实就是自旋锁,等待第一个线程释放锁,多线程压力比较大的时候用重量级锁(互斥锁)

6.4.2 锁升级过程

a. 无锁状态

对象刚创建时,并没有锁的介入,这时处于无锁状态。

b. 偏向锁(Biased Locking)

只需要用一个CAS操作和简单地判断比较,就可以让一个线程持续地拥有一个锁。

c. 轻量级锁

就像偏向锁的前提,是同步代码块在大多数情况下只有同一个线程访问的时候。

而轻量级锁的前提则是,线程在同步代码块里面的操作非常快,获取锁之后,很快就结束操作,然后将锁释放出来。

d. 重量级锁

相比起轻量级锁,再膨胀的锁,一般称之为重量级锁,因为是依赖于每个对象内部都有的monitor锁来实现的,而monitor又依赖于操作系统的MutexLock(互斥锁)来实现,所以一般重量级锁也叫互斥锁

7、JUC包

        JUC是java.util.concurrent包的简称,用于处理并发编程的工具包

同步工具:

  1. CountDownLatch(倒计时锁存器)、CyclicBarrier(循环屏障)、StampedLock(信号量)

并发集合:

  1. CurrentHashMap、CopyOnWriteLock、BlockingQueue

原子操作(cas原理):

  1. AtomicInteger、AtomicLong

锁:

  1. synchronized、ReentrantLock(重入锁)、ReentrantReadWriteLock(重入读写锁)、StampedLock(乐观读写锁)

相关文章:

JAVA基础-线程(Thread)、多线程(Multi-threaded)

1、知识铺垫 要想了解什么是线程,首先要搞明白线程与进程的区别,并行与并发的区别 1.1 线程与进程 进程:是指⼀个内存中运⾏的应⽤程序,每个进程都有⼀个独⽴的内存空间,⼀个应⽤程序可以同时运⾏多个进程&#xff1b…...

hystrix微服务部署

目录 一.启动nacos和redis 1.查看是否有nacos和redis 二.开始项目 1.hystrix1工程(修改一下工程的注册名字) 2.运行登录nacos网站查看运行效果(默认密码nacos,nacos) 3.开启第二个项目 hystrix2工程 4.关闭第二个项目 hyst…...

使用百度文心智能体创建多风格表情包设计助手

文章目录 一、智能定制,个性飞扬二、多元风格,创意无限 百度文心智能体平台为你开启。百度文心智能体平台,创建属于自己的智能体应用。百度文心智能体平台是百度旗下的智能AI平台,集成了先进的自然语言处理技术和人工智能技术&…...

【嵌入式裸机开发】智能家居入门3(MQTT服务器、MQTT协议、微信小程序、STM32)

前面已经写了两篇博客关于智能家居的,服务器全都是使用ONENET中国移动,他最大的优点就是作为数据收发的中转站是免费的。本篇使用专门适配MQTT协议的MQTT服务器,有公用的,也可以自己搭建 前言一、项目总览二、总体流程分析1、了解…...

css的背景background属性

CSS的background属性是一个简写属性,它允许你同时设置元素的多个背景相关的子属性。使用这个属性可以简化代码,使其更加清晰和易于维护。background属性可以设置不同的子属性。 background子属性 定义背景颜色 使用background-color属性 格式&#x…...

Cypress自动化测试实战:构建高效的前端测试体系

在快速迭代的软件开发环境中,前端自动化测试是保证代码质量和用户体验的重要手段。Cypress作为一款功能强大的前端自动化测试工具,凭借其丰富的特性、直观的API和高效的测试执行速度,赢得了众多开发者和测试团队的青睐。本文将深入探讨Cypres…...

【YOLO学习】YOLOv2详解

文章目录 1. 概述2. Better2.1 Batch Normalization(批归一化)2.2 High Resolution Classifier(高分辨率分类器)2.3 Convolutional With Anchor Boxes(带有Anchor Boxes的卷积)2.4 Dimension Clusters&…...

windows 录音编码为flv格式时,pcm采样格式

这里使用的是0x3e,转换为二进制: 0 0 1 1 1 1 1 0 前四个字节为3,表示Linear Pcm, 后4个字节1 1 1 0 表示44100HZ采样, 16个bit,单声道。 故,windows 音频采样不支持48000HZ频率...

Qt开发技巧(九)去掉切换按钮,直接传样式文件,字体设置,QImage超强,巧用Qt的全局对象,信号槽断连,低量数据就用sqlite

继续讲一些Qt开发中的技巧操作: 1.去掉切换按钮 QTabWidget选项卡有个自动生成按钮切换选项卡的机制,有时候不想看到这个烦人的切换按钮,可以设置usesScrollButtons为假,其实QTabWidget的usesScrollButtons属性最终是应用到QTabWi…...

51c自动驾驶~合集1

我自己的原文哦~ https://blog.51cto.com/whaosoft/11466109 #HTCL 超过所有视觉方案!HTCL:分层时间上下文问鼎OCC 本文是对ECCV2024接受的文章 HTCL: 的介绍,HTCL在SemanticKITTI基准测试中超过了所有基于相机的方法,甚至在和…...

Star 3w+,向更安全、更泛化、更云原生的 Nacos3.0 演进

作者:席翁 Nacos 社区刚刚迎来了 Star 突破 30000 的里程碑,从此迈上了一个新的阶段。感谢大家的一路支持、信任和帮助! Nacos /nɑ:kəʊs/是 Dynamic Naming and Configuration Service 的首字母简称,定位于一个更易于构建云原…...

PHP魔幻(术)方法

PHP中的魔幻方法,也被称为魔术方法(Magic Methods),是一组具有特殊功能的方法。这些方法在PHP中有固定的名称,并且会在特定的时机自动被PHP调用,而无需开发者显式调用。它们通常用于执行一些特殊的操作&…...

VS开发 - 静态编译和动态编译的基础实践与混用

目录 1. 基础概念 2. 直观感受一下静态编译和动态编译的体积与依赖项目 3. VS运行时库包含哪些主要文件(从VS2015起) 4. 动态库和静态库混用的情况 5. 感谢清单 1. 基础概念 所谓的运行时库(Runtime Library)就是WINDOWS系统…...

Golang | Leetcode Golang题解之第451题根据字符出现频率排序

题目: 题解: func frequencySort(s string) string {cnt : map[byte]int{}maxFreq : 0for i : range s {cnt[s[i]]maxFreq max(maxFreq, cnt[s[i]])}buckets : make([][]byte, maxFreq1)for ch, c : range cnt {buckets[c] append(buckets[c], ch)}an…...

零信任如何增强网络物理系统 (CPS) 安全性

远程访问对于管理关键基础设施至关重要,因为它允许企业优化和扩展运营并保持效率。然而,它也带来了许多安全漏洞,而且随着连接设备数量的增加,这些漏洞只会越来越多。 到 2025 年,企业和消费者环境中的物联网设备数量…...

V3D——从单一图像生成 3D 物体

导言 论文地址:https://arxiv.org/abs/2403.06738 源码地址:https://github.com/heheyas/V3D.git 人工智能的最新进展使得自动生成 3D 内容的技术成为可能。虽然这一领域取得了重大进展,但目前的方法仍面临一些挑战。有些方法速度较慢&…...

计算机网络期末复习真题(附真题答案)

前言: 本文是笔者在大三学习计网时整理的笔记,哈理工的期末试题范围基本就在此范畴内,就算真题有所更改,也仅为很基础的更改数值,大多跑不出这些题,本文包含简答和计算等大题,简答的内容也可能…...

Unity 的 UI Event System 是一个重要的框架

Unity 的 UI Event System 是一个重要的框架,用于处理用户界面中的输入事件。以下是它的主要特点和功能: 1. 事件管理 UI Event System 负责捕获和管理来自用户的输入事件,如鼠标点击、触摸、键盘输入等。 2. 事件传播 事件通过层次结…...

第十三章 集合

一、集合的概念 集合:将若干用途、性质相同或相近的“数据”组合而成的一个整体 Java集合中只能保存引用类型的数据,不能保存基本类型数据 数组的缺点:长度不可变 Java中常用集合: 1.Set(集):集合中的对象不按特定方式排序&a…...

子非线程池中物

线程池&#xff0c;又好上了 有任务队列 任务要处理就直接放到里面 预先创建好线程&#xff0c;本质上也是一个生产消费模型 线程池真是麻烦啊 我们可以直接沿用之前写过的代码&#xff0c;Thread.hpp: #pragma once #include <iostream> #include <functional&…...

Unraid的cache使用btrfs或zfs?

Unraid的cache使用btrfs或zfs&#xff1f; 背景&#xff1a;由于在unraid中添加了多个docker和虚拟机&#xff0c;因此会一直访问硬盘。然而&#xff0c;单个硬盘实在难以让人放心。在阵列盘中&#xff0c;可以通过添加校验盘进行数据保护&#xff0c;在cache中无法使用xfs格式…...

微服务实战——平台属性

平台属性 中间表复杂业务 /*** 获取分类规格参数&#xff08;模糊查询&#xff09;** param params* param catelogId* param type type"base"时查询基础属性&#xff0c;type"sale"时查询销售属性* return*/ Override public PageUtils listByCatelogId…...

半监督学习与数据增强(论文复现)

半监督学习与数据增强&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 半监督学习与数据增强&#xff08;论文复现&#xff09;概述算法原理核心逻辑效果演示使用方式 概述 本文复现论文提出的半监督学习方法&#xff0c;半监督学习&…...

css3-----2D转换、动画

2D 转换&#xff08;transform&#xff09; 转换&#xff08;transform&#xff09;是CSS3中具有颠覆性的特征之一&#xff0c;可以实现元素的位移、旋转、缩放等效果 移动&#xff1a;translate旋转&#xff1a;rotate缩放&#xff1a;scale 二维坐标系 2D 转换之移动 trans…...

SQL进阶技巧:统计各时段观看直播的人数

目录 0 需求描述 1 数据准备 2 问题分析 3 小结 如果觉得本文对你有帮助&#xff0c;那么不妨也可以选择去看看我的博客专栏 &#xff0c;部分内容如下&#xff1a; 数字化建设通关指南 专栏 原价99&#xff0c;现在活动价39.9&#xff0c;十一国庆后将上升至59.9&#…...

Stream流的终结方法

1.Stream流的终结方法 2.forEach 对于forEach方法&#xff0c;用来遍历stream流中的所有数据 package com.njau.d10_my_stream;import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.function.Consumer; import java.util…...

JavaWeb——Vue组件库Element(4/6):案例:基本页面布局(基本框架、页面布局、CSS样式、完善布局、效果展示,含完整代码)

目录 步骤 基本页面布局 基本框架 页面布局 CSS样式 完善布局 效果展示 完整代码 Element 的基本使用方式以及常见的组件已经了解完了&#xff0c;接下来要完成一个案例&#xff0c;通过这个案例让大家知道如何基于 Element 中的各个组件制作一个完整的页面。 案例&am…...

【c++】 模板初阶

泛型编程 写一个交换函数&#xff0c;在学习模板之前&#xff0c;为了匹配不同的参数类型&#xff0c;我们可以利用函数重载来实现。 void Swap(int& a, int& b) {int c a;a b;b c; } void Swap(char& a, char& b) {char c a;a b;b c; } void Swap(dou…...

R 语言 data.table 大规模数据处理利器

前言 最近从一个 python 下的 anndata 中提取一个特殊处理过的单细胞矩阵&#xff0c;想读入R用来画图&#xff08;个人比较喜欢用R可视化 &#xff09;&#xff0c;保存之后&#xff0c;大概几个G的CSV文件&#xff0c;如果常规方法读入R&#xff0c;花费的时间比较久&#x…...

Java 静态代理详解:为什么代理类和被代理类要实现同一个接口?

在 Java 开发中&#xff0c;代理模式是一种常用的设计模式&#xff0c;其中代理类的作用是控制对其他对象的访问。代理模式分为静态代理和动态代理&#xff0c;在静态代理中&#xff0c;代理类和被代理类都需要实现同一个接口。这一机制为实现透明的代理行为提供了基础&#xf…...

上海好的网站设计公司/开源cms建站系统

HBase vs Cassandra HBase Cassandra语言JavaJava出发点BigTableBigTable and DynamoLicenseApacheApacheProtocolHTTP/REST (also Thrift)Custom, binary (Thrift)数据分布表划分为多个region存在不同region server上改进的一致性哈希&#xff08;虚拟节点&#xff09;存储目标…...

网站建设7个基本流程/seo外包

在python中&#xff0c;给一个对象赋值&#xff0c;实际上就是对象对内存空间存储的值的引用。当我们把对象赋值给另一个变量的时候&#xff0c;这个变量并没有拷贝这个对象&#xff0c;而只是拷贝了这个对象的引用而已。一般情况下我们会通过三种方法来实现拷贝对象的引用。Py…...

徐州建筑网站/直播营销策略有哪些

转载于&#xff1a;https://blog.csdn.net/room08304/article/details/77995179 cv::DataType<_Tp>在C中作为一个类&#xff0c;有两种构造方法&#xff1a; struct class 在Opencv对象的容器中。...

网站内容建设招标/目前最新的营销方式有哪些

12、浮动 特点&#xff1a;将当前元素脱离文档流 float: left 即左浮动 float: right 即右浮动 注&#xff1a;*父与子元素&#xff0c;设置子元素浮动不能超出父元素的范围 *多个元素均设置为浮动时&#xff0c;将自动排列(水平方向) *兄弟元素&#xff0c;后一个元素设置…...

可以做ppt的软件/东莞网站优化公司

阅读目录 一 什么是异常二 异常的种类三 异常处理四 什么时候用异常处理一 什么是异常 异常就是程序运行时发生错误的信号&#xff08;在程序出现错误时&#xff0c;则会产生一个异常&#xff0c;若程序没有处理它&#xff0c;则会抛出该异常&#xff0c;程序的运行也随之终止&…...

网站广告策划/友情链接代码美化

Linux操作系统案例教程课后习题答案第一章一 1.(D)2.(B,C)3.(A,B,D)4.(A,C,D ) 5.( B ) 6.(D ) 7.( B ) 8.( C) 9.( A ) 第二章一 1.(A)2.(B)3.(A,B)4.(B,D ) 5.( A,B ) 6.(B ) 7.( A ) 8.( C) 9.( A,B,D ) 10(A,B,C,E) 11( B )二&#xff0e;Shutdown –h O 22&#xff1a;00第…...