万字长文详解Java线程池

ISO18000-6B/6C(EPC C1G2)两个射频识别(RFID)标准协议的技术特点 目前读写器基本上是采用IMPINJ的R2000芯片和E710芯片开发,因为ISO18000-6B标准的现在应用很少,E710芯片已经不再支持ISO18000-6B标准,选择上就只有采用R2000芯片开发的UR6258超高频读写器以及手持机,这个在项目应用上需要留意。尽管ISO18000-6B标准具有上述优点,但也存在一些不足之处,特别是多标签阅读性能远远满足不了现在的应用需求,近年来发展停滞,绝大部分应用已经被ISO18000-6C(EPC C1G2)取代;#RFID# #物联网# #标准协议# 阅读详情

为什么是需要使用线程池?

如果直接创建线程,存在以下问题:
1、反复创建线程系统开销比较大,每个线程的创建和销毁都需要时间,如果线程执行的任务比较简单,那么创建销毁线程占用资源比线程本身执行任务销毁的资源还要多。
2、过多的线程会消耗更多的内存,也会造成过多的上下文切换,使得系统不稳定。
使用线程池优点:
1、线程池可以控制线程生命周期的开销问题,同时加快响应速度。线程池的线程是可以复用的,通过少量的线程执行大量的任务。
2、线程池可以统筹内存和CPU的使用,避免资源使用不当。线程池可以根据配置和任务数量灵活控制线程数量。
3、线程池可以统一管理资源。

线程池各个参数的含义

属性名字作用
corePoolSize核心线程数当线程池运行线程少于corePoolSize时,将创建一个新的线程来处理请求,即使其他线程处于空闲状态
threadFactory线程工厂用于创建线程的工厂
workQueue队列用于保留任务并移交工作线程的阻塞队列
maximunPoolSize最大线程数线程池允许开始最大线程数
handler拒绝策略在线程池添加任务时候,两种情况下触发拒绝策略:1、线程池运行状态不是RUNNING;2、线程池达到最大线程数,并且阻塞队列已经满。
keepAliveTime保持存活时间当线程池线程数大于核心线程数时,多余的线程空闲时间超过keepAliveTime时会被终止。

线程创建时机

corePoolSize,maximumPoolSize

corePoolSize 指的是核心线程数,线程池初始化时线程数默认为 0,当有新的任务提交后,会创建新线程执行任务,如果不做特殊设置,此后线程数通常不会再小于 corePoolSize ,因为它们是核心线程,即便未来可能没有可执行的任务也不会被销毁。随着任务量的增加,在任务队列满了之后,线程池会进一步创建新线程,最多可以达到 maximumPoolSize 来应对任务多的场景,如果未来线程有空闲,大于 corePoolSize 的线程会被合理回收。所以正常情况下,线程池中的线程数量会处在 corePoolSize 与 maximumPoolSize 的闭区间内。

线程池的几个特点:

  • 线程池希望保持较少的线程数,并且只有在负载变得很大时才增加线程。

  • 线程池只有在任务队列填满时才创建多于 corePoolSize 的线程,如果使用的是无界队列(例如 LinkedBlockingQueue),那么由于队列不会满,所以线程数不会超过 corePoolSize。

  • 通过设置 corePoolSize 和 maximumPoolSize 为相同的值,就可以创建固定大小的线程池。

  • 通过设置 maximumPoolSize 为很高的值,例如 Integer.MAX_VALUE,就可以允许线程池创建任意多的线程。

线程池状态

RUNNING:接受新任务并处理排队的任务。
SHUTDOWN:不接受新任务,但处理排队的任务。
STOP:不接受新任务,不处理排队的任务,并且中断进行中的任务。
TIDYING:所有的任务都已经终止,workerCount为零,线程转换到TIDYING状态将运行terminated()钩子方法。
TERMINATED:terminated()已经完成。

线程池状态转换

线程池有哪些拒绝策略

拒绝时机

1、线程池不在RUNNING状态,线程池调用shutdown等方法关闭线程池后,即便线程池内部依然存在没有执行完的任务正在执行,但是线程池已经关闭,此时再向线程池内提交任务,就会遭到拒绝。
2、线程池没有能力继续处理新提交的任务。线程池达到最大线程数,且队列已经满的情况。

4种拒绝策略


AbortPolicy:在拒绝任务时,会抛出异常。(异常:RejectedExecutionException的RuntimeException)
DiscardPolicy:当提交新任务时候,直接抛弃掉,不做任何通知。
DiscardOldestPolicy:当提交新任务时候,丢弃掉存活时间长的队列头任务,腾出空间给新的任务.
CallerRunsPolicy:当有新任务提交后,如果线程池没被关闭且没有能力执行,则把这个任务交于提交任务的线程执行,也就是谁提交任务,谁就负责执行任务。

阻塞队列

ArrayBlockingQueue:基于数组结构的有界阻塞队列,按先进先出对元素进行排序。
LinkedBlockingQueue:基于链表结构的有界/无界阻塞队列,按先进先出对元素进行排序,吞吐量通常高于ArrayBlockingQueue。Executors.newFixedThreadPool使用了该队列。
SynchronousQueue:不是一个真正的队列,而是一种在线程之间移交的机制。要将一个元素放入SynchronousQueue中,必须有另一个线程正在等待接受这个元素。如果没有线程等待,并且线程池的当前大小小于最大值,那么线程池将创建一个线程,否则根据拒绝策略,这个任务将被拒绝。使用直接移交将更高效,因为任务会直接移交给执行它的线程,而不是被放在队列中,然后由工作线程从队列中提取任务。只有当线程池是无界的或者可以拒绝任务时,该队列才有实际价值。Executors.newCachedThreadPool使用了该队列。
PriorityBlockingQueue:具有优先级的无界队列,按优先级对元素进行排序。元素的优先级是通过自然顺序或 Comparator 来定义的。

6 种常见的线程池?

FixedThreadPool、CachedThreadPool、ScheduledThreadPool、SingleThreadExecutor、SingleThreadScheduledExecutor、ForkJoinPool

FixedThreadPool

FixedThreadPool 是一个固定大小的线程池。这意味着它在创建时会同时创建固定数量的线程,并且这些线程会一直存在,直到线程池被关闭。
关键特性:
固定线程数量:一旦创建,线程池中的线程数量就不会再改变,除非线程由于某种原因终止,那么线程池可能会创建新线程来替换它们。
线程复用:FixedThreadPool 会重用之前构造的线程,而不是每次执行任务时都创建新线程,这样可以减少线程创建和销毁的开销。
任务队列:当所有线程都在忙碌时,新提交的任务会被放入一个工作队列中等待执行。这个队列可以是无界的,也可以是有界的,具体取决于线程池的构造方式。
线程池管理:FixedThreadPool 提供了方法来管理线程池,比如关闭线程池、获取当前线程数量、获取已完成的任务数量等。
异常处理:如果任务执行时抛出未检查的异常,那么这个线程将会终止,线程池会创建新线程来替换它。
公平性:可以通过构造函数参数来指定线程池是否应该按照任务提交的顺序来执行它们(公平性)。默认情况下,FixedThreadPool 是非公平的,即线程池中的线程可能会以非 FIFO 的顺序执行任务。

CachedThreadPool

CachedThreadPool 是一种可根据需要创建新线程的线程池,这些线程在执行完任务后不会立即销毁,而是会被缓存起来供以后使用。如果线程在指定的时间内没有被分配新任务,那么它们将被终止并从缓存中移除。
关键特性:
线程缓存:CachedThreadPool 会尝试重用已有的线程,而不是每次都创建新线程。
动态线程创建:当现有线程不足以处理新任务时,线程池会创建新线程。
线程回收:如果一个线程在指定的空闲时间内没有被使用,它将被终止。
无界线程数量:理论上,CachedThreadPool 可以创建的线程数量没有上限,但实际上受限于系统资源和构造函数中指定的保持空闲线程存活时间的上限。
保持活动时间:可以设置一个保持活动时间,在这个时间内如果线程空闲,它将被终止。
非核心线程:由于它的特性,CachedThreadPool 更适合用于短生命周期的异步任务。

ScheduledThreadPool

ScheduledThreadPool 允许用户在给定的延迟后运行任务,或者定期重复执行任务。这个线程池能够满足需要任务调度的场景,比如延时执行、定时执行等。
关键特性:
延时执行:可以安排任务在一定的延迟之后执行。
周期性执行:可以安排任务按照指定的周期重复执行。
线程复用:ScheduledThreadPool 会重用之前构造的线程来执行新的任务,减少线程创建和销毁的开销。
灵活性:可以灵活地安排单次执行或多次执行的任务。
固定线程数量:创建时可以指定线程池的大小,这个大小是固定的。

SingleThreadExecutor

SingleThreadExecutor 创建一个单线程的执行器。这个线程池中只有一个线程工作,所有提交给该执行器的任务都会按照顺序依次执行。
关键特性:
单线程执行:只有一个线程在工作,任务会按照它们被提交的顺序依次执行。
任务队列:如果线程正在执行任务,后续提交的任务会被放入队列中等待执行。
线程复用:SingleThreadExecutor 会重用同一个线程来执行多个任务。
避免线程创建开销:由于只有一个线程,避免了频繁创建和销毁线程的开销。
错误传递:如果一个任务执行失败,后续任务将不会执行,线程池会关闭。

SingleThreadScheduledExecutor

SingleThreadScheduledExecutor 是 ScheduledExecutorService 接口的一个具体实现。与 SingleThreadExecutor 类似,SingleThreadScheduledExecutor 也只有一个工作线程,但它专门用于延迟执行或定期执行任务。
关键特性:
单线程:只有一个线程用于执行所有任务,确保任务按顺序执行。
定时任务:可以安排任务在给定的延迟后执行,或者定期执行。
可调度性:提供了灵活的调度功能,包括单次执行、固定频率执行和固定延迟执行。
线程复用:与 SingleThreadExecutor 一样,它会重用同一个线程来执行多个任务。
错误处理:如果任务执行过程中抛出异常,默认情况下,后续的任务将不会执行,线程池会关闭。可以通过适当的异常处理逻辑来避免这种情况。

ForkJoinPool

ForkJoinPool 是 一个专门用于分治任务模型的线程池实现。它特别适合于可以递归分解为更小任务的问题,比如大规模数值计算、图像处理、大数据处理等。
关键特性
工作窃取算法:ForkJoinPool 使用工作窃取算法来均衡地分配任务给线程。每个线程维护一个双端队列,用于存储任务。线程可以从队列的两端出队任务执行,但通常从自己的那一端出队,而从其他线程的队列另一端窃取任务。
分治任务模型:适合于可以递归分解为更小任务的问题。任务被分解(fork)成更小的任务并行执行,最终结果通过合并(join)操作得到。
轻量级任务:ForkJoinPool 特别适合执行大量小任务,这些任务可以快速执行并完成。延迟执行:任务通常在提交后不会立即执行,而是延迟到工作线程可用时才执行。
可扩展性:ForkJoinPool 可以很好地扩展到多核处理器,并且可以根据系统的处理器数量动态调整线程数量。专用任务类:ForkJoinPool 使用 RecursiveTask 和 RecursiveAction 类来表示有返回值和无返回值的任务。

线程池线程数多少合适?

线程池处理的任务通常分为cpu密集型任务、IO密集型任务。

cpu密集型任务核心线程数设置

加密、解密、压缩、计算等一系列需要大量耗费 CPU 资源的任务
核心线程数: 这样的任务最佳的线程数为 CPU 核心数的 1~2 倍
原因: 因为计算任务非常重,会占用大量cpu资源,此时每个核心线程都是满负荷工作。设置过多的线程数会造成不必要的上下文切换。

IO密集型任务核心线程数设置

数据库、文件的读写,网络通信等任务,这种任务的特点是并不会特别消耗 CPU 资源,但是 IO 操作很耗时,总体会占用比较多的时间。
核心线程数: 最大线程数一般会大于 CPU 核心数很多倍,线程数 = CPU 核心数 *(1+平均等待时间/平均工作时间)。例如我们有个定时任务,部署在4核的服务器上,该任务有100ms在计算,900ms在I/O等待,则线程数约为:4 * 1 * (1 + 900 / 100) = 40个。
原因:因为 IO 读写速度相比于 CPU 的速度而言是比较慢的,如果我们设置过少的线程数,就可能导致 CPU 资源的浪费。而如果我们设置更多的线程数,那么当一部分线程正在等待 IO 的时候,它们此时并不需要 CPU 来计算,那么另外的线程便可以利用 CPU 去执行其他的任务,互不影响,这样的话在任务队列中等待的任务就会减少,可以更好地利用资源。

使用线程池队列需要注意什么?

有界队列:需要注意线程池满后。被拒绝的任务如何处理。
无界队列:如果提交任务大于线程池处理任务的速度时候 ,可能导致内存溢出。

如何根据实际需要,定制自己的线程池?

定制自己的线程池需要考虑多个因素,包括任务类型、并发量、资源限制和业务需求。定制线程池时需要考虑的关键步骤和参数:
确定核心线程数(corePoolSize):核心线程数是指线程池中始终保持激活的线程数量,即使它们处于空闲状态。对于CPU密集型任务,核心线程数通常设置为处理器核心数的1至2倍。对于IO密集型任务,可以设置更多的线程,因为线程会在等待IO操作时释放CPU。
确定最大线程数(maximumPoolSize):最大线程数是指线程池中允许的最大线程数量。如果任务数量波动很大,或者有大量短期任务,可能需要设置一个较高的最大线程数。
选择阻塞队列:阻塞队列用于存储等待执行的任务。常见的阻塞队列有 LinkedBlockingQueue、ArrayBlockingQueue、SynchronousQueue 等。队列的选择会影响线程池如何管理等待任务和内存使用。
设置线程工厂(threadFactory):线程工厂用于创建新线程,可以自定义线程的名称、优先级、守护进程状态等。自定义线程工厂可以帮助你更好地监控和调试线程池。
设置拒绝策略(rejectedExecutionHandler):当任务太多,无法被线程池及时处理时,需要一个拒绝策略来处理新任务。常见的拒绝策略包括AbortPolicy、DiscardPolicy、DiscardOldestPolicy、CallerRunsPolicy。也可以实现自定义的拒绝策略。
设置保持活动时间(keepAliveTime):非核心线程在空闲状态下等待新任务的最长时间。如果任务是周期性的,可以设置一个合适的保持活动时间。
设置时间单位(timeUnit):keepAliveTime 参数的时间单位,如 TimeUnit.SECONDS、TimeUnit.MILLISECONDS 等。
考虑是否允许核心线程超时:如果允许,即使核心线程也会在空闲时被终止。
考虑工作线程的优先级:可以为工作线程设置不同的优先级,以影响任务的执行顺序。
考虑是否需要单线程执行:如果任务之间需要严格的顺序执行,或者有共享状态需要严格同步,可能需要使用单线程执行器。

线程只能在任务到达时才启动吗?

默认情况下,即使是核心线程也只能在新任务到达时才创建和启动。但是我们可以使用 prestartCoreThread(启动一个核心线程)或 prestartAllCoreThreads(启动全部核心线程)方法来提前启动核心线程。

核心线程怎么实现一直存活?

抛出异常返回特殊值一直阻塞超时退出
插入add(e)offer(e)put(e)offer(e,time,unit)
移除remove()poll()take()poll(time,unit)
检查element()peek()不可用不可用

核心线程在获取任务时,通过阻塞队列的 take() 方法实现的一直阻塞(存活)。

非核心线程如何实现在 keepAliveTime 后死亡?

原理同上,也是利用阻塞队列的方法,在获取任务时通过阻塞队列的 poll(time,unit) 方法实现的在延迟死亡。

非核心线程能成为核心线程吗?

虽然我们一直讲着核心线程和非核心线程,但是其实线程池内部是不区分核心线程和非核心线程的。只是根据当前线程池的工作线程数来进行调整,因此看起来像是有核心线程于非核心线程。

如何终止线程池?

终止线程池主要有两种方式:
shutdown:“温柔”的关闭线程池。不接受新任务,但是在关闭前会将之前提交的任务处理完毕。
shutdownNow:“粗暴”的关闭线程池,也就是直接关闭线程池,通过 Thread#interrupt() 方法终止所有线程,不会等待之前提交的任务执行完毕。但是会返回队列中未处理的任务。

线程池ctl

ctl怎么设计的?

ctl是打包两个概念字段的原子整数。
workerCount:指示线程的有效数量。
runState:线程池状态:RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED
ctl int类型、32位。高3位为runState的,低29位为workerCount。
 

例如,当我们的线程池运行状态为 RUNNING,工作线程个数为3,
则此时 ctl 的原码为:1010 0000 0000 0000 0000 0000 0000 0011

为什么要这样设计?

runState 和 workerCount 是线程池正常运转中的2个最重要属性,线程池在某一时刻该做什么操作,取决于这2个属性的值。
因此无论是查询还是修改,我们必须保证对这2个属性的操作是属于“同一时刻”的,也就是原子操作,否则就会出现错乱的情况。如果我们使用2个变量来分别存储,要保证原子性则需要额外进行加锁操作,这显然会带来额外的开销,而将这2个变量封装成1个 AtomicInteger 则不会带来额外的加锁开销,而且只需使用简单的位操作就能分别得到 runState 和 workerCount。
由于这个设计,workerCount 的上限 CAPACITY = (1 << 29) - 1,对应的二进制原码为:0001 1111 1111 1111 1111 1111 1111 1111(不用数了,29个1)。
通过 ctl 得到 runState,只需通过位操作:ctl & ~CAPACITY。
~(按位取反),于是“~CAPACITY”的值为:1110 0000 0000 0000 0000 0000 0000 0000,只有高3位为1,与 ctl 进行 & 操作,结果为 ctl 高3位的值,也就是 runState。
通过 ctl 得到 workerCount 则更简单了,只需通过位操作:c & CAPACITY。

从工具选型到落地实践:吃透 SAP Fiori Launchpad 配置工具体系 摘要: SAP Fiori Launchpad配置远非简单添加应用和分配角色,涉及技术目录、业务目录、Spaces/Pages等多层管理。官方推荐新工具分工:技术目录用FLPAM维护应用定义,业务目录用FLPCM编排应用组合,Spaces/Pages优化用户体验布局,而传统Groups模式已被标记弃用。这种分层治理模式(定义层-编排层-展示层)能有效解决传输混乱、升级兼容性问题,尤其适合大规模项目实施。关键在于区分技术配置与业务呈现,避免将所有功能堆砌在单一旧工具中。(149字) 阅读详情

相关推荐

STM32最小系统硬件组成详解

STM32最小系统硬件组成详解 0组成: 电源 复位 时钟 调试接口 启动 1、电源 : 一般3.3V LDO供电 加多个0.01uf去耦电容 2、复位:有三种复位方式:上电复位、手动复位、程序自动复位 通常低电平复位:(51单片机高电平复位,电容电阻位置调换) 上电复位,在上电瞬间,电容充电,RESET出现短暂的低电平,该低电平持续时间由电阻和电容共同决定,计...

alala120的博客 12万+

(史上最全)线程池

虽然线程给我们程序带来了更高的执行效率,但是线程不是创建的越多越好,那么线程创建的过多,会带来什么问题呢?首先线程的创建和销毁都是很耗时很浪费性能的操作(new三五个Thread还好,我需要一千个线程呢?线程之间频繁的进行上下文切换,增加系统的负载为了解决线程复用。也就是说线程用完后不销毁,放到池子里等着新任务的到来,反复利用N个线程来执行所有新老任务。这带来的开销只会是那N个线程的创建,而不是每来一个请求都带来一个线程的从生到死的过程。

nice66660的博客 1129

x86架构学习之中断

外部中断,一般是由CPU的外部引脚电信号触发,这些引脚留给硬件厂商去定义中断,例如主板厂商可以将USB中断挂载70号中断引脚上,MCU厂商可以将片上外设(SPI、I2C等)的中断挂载在指定中断线上。中断描述符主要用于说明该中断的入口地址,中断描述符表则是将中断描述符一项一项管理在一个数组中,每一项中断描述符占用8个字节(64位模式下,占用16字节),其。简称中断,后文如果没特别说明,中断都指外部中断,由外部IO事件触发,由于时钟源来自CPU外部,与CPU时钟不同源,因此是异步事件。

qq_26962739的博客 1572

万字长文:带你透彻理解“线程池”

什么是线程池为什么使用线程池线程池有哪些优势线程池其实就是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。这里的线程就是我们前面学过的线程,这里的任务就是我们前面学过的实现了Runnable或Callable接口的实例对象;网购商品秒杀云盘文件上传和下载12306网上购票系统等总之,只要有并发的地方、任务数量大或小、每个任务执行时间长或短的都可以使用线程池;只不过在使用线程池的时候,注意一下设置合理的线程池大小即可;

2401_83384536的博客 864

Langchain分割方式

【代码】Langchain分割方式。

2897

华为OD机试 新系统 双机位C卷 往年真题 机考题库(持续收录中)以及算法考点详解

每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天优快云在线答疑。

学Java,找哪吒 7万+

深入详解Java线程池——ThreadPoolExecutor

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34309543的博客 156

【GlobalMapper精品教程】027:路径剖面和和视线工具的使用

路径剖面视线工具允许您使用加载的高程数据集沿用户指定的路径获取垂直剖面。要定义生成3D路径剖面所遵循的路径,只需单击鼠标左键选择路径的点,然后石键单击以结束路径。出现一个带有剖面的对话框,允许您设置视线分析或优化端点。

智慧空间实验室 2051

Springboot整合Fastdfs上传图片、缩略图、下载文件、需求:文件转存方案(springboot整合线程池多线程实现)

Springboot整合Fastdfs上传图片、缩略图、下载文件、需求:文件转存方案(springboot整合线程池多线程实现

鸢尾_的博客 1967

Fluent验证案例03:管道中湍流流动压降计算——采用kw-sst模型计算压降更为准确。

阅读(4053) 评论(0)本案例利用Fluent计算管道中湍流流动压降。

qq_15963745的博客 878

K230目标识别数字提问:模型只能识别近距离的目标,稍远一点就无法正确检测...如何解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1901

一图看懂线程池工作原理

jiaotongqu6470的博客 402

别再用第三方黑盒库了!从零手写C#+YOLOv12推理全流程,框位准、可定制、调试快10倍

从零手写YOLO推理框架,不是为了造轮子,而是为了完全掌控代码,工业现场的需求千变万化,第三方黑盒库根本没法满足所有需求。这套代码我已经在东莞长安的3家PCB厂、深圳南山的2家3C电子厂落地了,稳定运行6个月,没有出过任何问题。如果有什么问题或者需要扩展的功能,都可以在评论区交流。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 328

【005】万字长文: 什么是线程池?在Java中如何使用线程池?

线程池是一种复用线程、降低资源开销的并发工具。Java中通过Executor框架实现,推荐使用ThreadPoolExecutor手动创建(可灵活配置核心线程数、队列和拒绝策略),而非Executors工具类(存在OOM风险)。线程池核心思想是复用线程,避免频繁创建销毁,提高响应速度并便于管理。使用时需提交Runnable/Callable任务,并注意合理关闭线程池。

编程技术圈 2351

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

两万字长文-最全的线程池详解

int corePoolSize, // 核心线程数:线程池中始终保持存活的线程数,即使它们处于空闲状态。int maximumPoolSize, // 最大线程数:线程池中允许的最大线程数。当队列满了并且当前线程数小于最大线程数时,会创建新的线程来处理任务。long keepAliveTime, // 线程空闲时间:非核心线程的空闲时间超过这个时间,就会被回收。指定数值和时间单位一起使用。

图你怀中安稳的博客 1208

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

万字长文!七个方面带你玩转Java线程池

点击上方 "程序员小乐"关注,星标或置顶一起成长后台回复“大礼包”有惊喜礼包!关注订阅号「程序员小乐」,收看更多精彩内容每日英文Remember every who t...

程序员小乐 378

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

超赞!万字长文细数 Java 线程池的原理

你知道的越多,不知道的就越多,业余的像一棵小草!你来,我们一起精进!你不来,我和你的竞争对手一起精进!编辑:业余草来源:cnblogs.com/dolphin0520/p/3932921...

xmt1139057136的专栏 441

2025最新JAVA面试八股文,万字长文!

在 Java 中,线程是程序执行的最小单位。它可以执行一个任务或者一系列任务。线程是 CPU 调度的基本单位,多个线程可以并发执行,从而提高程序的执行效率。例如,在一个文本编辑器程序中,可以有一个线程专门用于处理用户的输入,另一个线程用于自动保存文档,这样可以让用户在输入文字的同时,程序后台自动保存文档,提高用户体验。当一个线程被剥夺cpu使用权时,切换到另外一个线程执行死锁指多个线程在执行过程中,因争夺资源造成的一种相互等待的僵局篇幅限制下面就只能给大家展示小册部分内容了。

2401_89221867的博客 889

《JUC》万万万万字长文解析!

四万字长文解析 juc,涵盖线程、内存模型、锁、线程池、原子类、同步器、并发容器、并发编程模式、并发编程应用等。

后端为主,前端为辅。 4238

2 w字长文带你深入理解线程池

前言 线程池可以说是 Java 进阶必备的知识点了,也是面试中必备的考点,可能不少人看了这篇文章后能对线程池工作原理说上一二,但这还远远不够,如果碰到比较有经验的面试官再继续追问,很可能...

weixin_41385912的博客 2227

万字长文扫盲JUC基础

JUC基础篇,锁

ljz66254的博客 1221

2 万字长文详解 10 大多线程面试题|原力计划

作者 |ZZZhonngger责编 | 伍杏玲出品 | 优快云博客Volatile相关1.请谈谈你对 volatile 的理解答:volatile ...

优快云资讯 2140

【深度长文】深入分析Java线程池——ThreadPoolExecutor

一篇深入的线程池源码研究博客,图片形象生动、代码注释详细。

wzz2333的博客 1236

万字长文详解java多并发知识点

CAS的全称是: Compare And Swap(比较再交换),它体现的一种乐观锁的思想,在无锁情况下保证线程操作共享数据的原子性。在JUC( java.util.concurrent )包下实现的很多类都用到了CAS操作AbstractQueuedSynchronizer(AQS框架)AtomicXXX类例子:我们还是基于刚才学习过的JMM内存模型进行说明线程1与线程2都从主内存中获取变量int a = 100,同时放到各个线程的工作内存中。

weixin_60800735的博客 197
上一篇: 万字长文详解Java线程知识
下一篇: 最全的 synchronized 面试题解析
Java_2017_csdn
博客等级 码龄10年 329粉丝 49原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值