标签:Word VBA 有多种方法可以使我们在创建、打开或关闭Word文档时自动运行宏。...这样,每当创建基于该模板的文档时,将运行Document_New()过程;每当打开基于该模板的文档时,会运行Document_Open()过程;每当关闭基于该模板的文档时,会运行Document_Close...注意,这些过程不是全局的,只有在创建、打开或关闭基于模板的文档时才会触发这些过程。...如果存储在除Normal.dotm以外的任何模板中,这些事件的行为方式与Document事件相同,当创建、打开或关闭附加到模板的文档时,它们将被触发。...然而,如果存储在Normal.dotm中,则它们将全局运行,换句话说,当创建、打开或关闭任何文档时,它们都将被触发。
线程是进程内的一个执行路径,一个进程可以包含多个线程,这些线程共享进程的内存空间和其他资源,线程是执行计算机程序的最小单位,它可以独立执行任务,也可以协作合作与其他线程共同完成任务,线程之间的调度和切换由操作系统的线程调度器负责...二、线程如何创建 在 Java 中,有两种方式可以创建线程,请同学们认真学习。...无论使用哪种方式创建线程,最终都需要调用 start() 方法来启动线程,使其进入就绪状态,等待被调度执行,在 run() 方法中编写线程的具体执行逻辑,通过创建线程对象并启动线程,可以实现多线程的并发执行...并发编程:Java 线程用于实现并发编程,允许多个任务在同一时间段内同时执行,提高程序的性能和响应能力,可以使用多线程来处理大量的并行任务,例如在服务器中处理多个客户端请求、Web服务器请求、多线程爬虫等...五、线程面试题 什么是线程? 线程与进程的区别是什么? Java 中如何创建线程? 什么是线程安全?如何确保线程安全? 线程的生命周期是怎样的?
,这样会导致卡死 DLL_PROCESS_DETACH: StopMyThreadsAndWaitEnd(); // 停止并等待线程结束(或直接结束进程),这样会导致卡死...以上都是题外话,本文主要说明在DLL入口函数里面创建和退出线程为什么卡死和如何解决的问题。...1)在 DLL_PROCESS_ATTACH 事件中 创建线程 出现卡死的问题 通常情况下在这事件中仅仅是创建并唤醒线程,是不会卡死的,但如果同时有等待线程正式执行的代码,则会卡死,因为在该事件中...实际上如果是通过LoadLibrary加载DLL,则会在LoadLibrary结束前后的某一时刻正式执行)。...解决办法同样是避免在 DLL_PROCESS_DETACH事件中结束线程,那么我们可以在该事件中,创建并唤醒另外一个线程,在该新的线程里,结束需要结束的线程,并在完成后结束自身即可。
UI控件时,涉及到跨线程修改UI,需要使用委托,比如如下: this.Invoke((MethodInvoker)delegate {...btnRefresh.Enabled = true; }); 但是假如在多线程操作还没完成的时候,我就提前关闭窗体,则会引发InvalidOperationException...,提示 “在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke” ,并且如果没有捕获到,则可能导致程序崩溃,直接关闭。...发现需要判断控件的IsHandleCreated和IsDisposed等属性,并且如果还有错误,可以再捕获InvalidOperationException异常,避免程序崩溃 但是在项目中有太多需要修改UI的地方,每次涉及到...method(); } } } 代码中并没有专门捕获InvalidOperationException,因为如代码中这样判断之后,不再会出现 窗口句柄未创建
对于我们使用的线程池 ThreadPoolExecutor 来说,停止线程池的方法有以下两个: shutdown():优雅的关闭线程池,即不再接受新任务,但会等待已提交任务(包括正在执行的任务和在队列中等待的任务...() 方法后,程序会等待线程池中的所有任务全部执行完在关闭,再次期间线程池会拒绝加入新任务,并调用线程池的拒绝策略。...使用锁可以确保这些操作的原子性和一致性,避免多个线程同时进行关闭操作导致数据不一致或出现意外情况 检查关闭权限:在关闭之前进行状态检查可以确保关闭操作是合法的,避免在不适当的时候进行关闭。...将状态设置为 SHUTDOWN:阻止新任务提交但完成现有任务。 中断空闲线程。 调用 onShutdown 方法(钩子方法):可能用于在关闭时执行一些特定的清理或自定义操作,比如释放资源等。...尝试终止线程池:如果所有任务已完成的情况下,会真正的终止线程池。 shutdown() 方法的执行流程如下图所示: 课后思考 为什么需要关闭线程池?关闭线程池的场景有哪些?
) 方法后,程序会等待线程池中的所有任务全部执行完在关闭,再次期间线程池会拒绝加入新任务,并调用线程池的拒绝策略。...使用锁可以确保这些操作的原子性和一致性,避免多个线程同时进行关闭操作导致数据不一致或出现意外情况检查关闭权限:在关闭之前进行状态检查可以确保关闭操作是合法的,避免在不适当的时候进行关闭。...将状态设置为 SHUTDOWN:阻止新任务提交但完成现有任务。中断空闲线程。...钩子方法):可能用于在关闭时执行一些特定的清理或自定义操作...尝试终止线程池:如果所有任务已完成的情况下,会真正的终止线程池。shutdown() 方法的执行流程如下图所示:课后思考为什么需要关闭线程池?关闭线程池的场景有哪些?
start() 方法启动新线程,并在新线程中执行 run() 方法。...如果线程修改了变量的值,虚拟机会在某个时刻把修改后的值回写到主内存,但是,这个时间是不确定的; volatile 关键字的目的是告诉虚拟机: 每次访问变量时,总是获取主内存的最新值; 每次修改变量后,立刻回写到主内存...如果有新任务,就分配一个空闲线程执行。...使用 shutdown() 方法关闭线程池的时候,它会等待正在执行的任务先完成,然后再关闭。...在调用 get() 时,如果异步任务已经完成,我们就直接获得结果。如果异步任务还没有完成,那么 get() 会阻塞,直到任务完成后才返回结果。
具体组成部分包括: a、线程池管理器(ThreadPool)用于创建和管理线程池,包括创建线程池、销毁线程池,添加新任务。...- newFixedThreadPool:创建固定大小的线程池。 每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。...shutdown() 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。...1.当线程池小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。...,空闲时间达到keepAliveTime时,关闭空闲线程 6.当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime
util.concurrent中容器在迭代时,可以不封装在synchronized中,可以保证不抛异常,但是未必每次看到的都是"最新的、当前的"数据。...具体组成部分包括: a、线程池管理器(ThreadPool)用于创建和管理线程池,包括创建线程池、销毁线程池,添加新任务。...- newFixedThreadPool:创建固定大小的线程池。 每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。...shutdown() 启动一次顺序关闭,执行以前提交的任务,但不接受新任务。...,空闲时间达到keepAliveTime时,关闭空闲线程 6.当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime
,当一个新任务通过execute提交的时候: 如果当前运行的线程数小于corePoolSize就新建线程; 如果当前线程数在corePoolSize与maximumPoolSize之间,则只有在队列满的时候才会创建新的线程...terminated在所有任务都已经完成,并且所有工作者线程关闭后会调用,此时也可以用来执行发送通知、记录日志等等。...缺点:每次只能处理一个请求,新请求到来时,必须等到正在处理的请求处理完成,才能接收新的请求 显示的创建多线程 为每个请求创建新的线程提供服务 缺点: 线程的创建和销毁都有一定的开销,延迟对请求的处理...线程池策略通过实现预估好的线程需求,限制并发任务的数量,重用现有的线程,解决每次创建线程的资源耗尽、竞争过于激烈和频繁创建的问题,也囊括了线程的优势,解耦了任务提交和任务执行。...核心思路为为每一幅图像下载都创建一个独立的任务,并在线程池中执行他们,从而将串行的下载过程转换为并行的过程 获取页面的广告 广告展示如果在一定的时间以内没有获取,可以不再展示,并取消超时的任务。
为了解决这个问题,进行程序设计时,可能会考虑在程序初始化时,预先创建一批所需对象,并存储到池中,或者根据需要即时创建对象,并在使用完成后,将对象添加到池中,这样,当程序需要(再次)使用对象时,可以直接从池中直接获取现有的对象...按需创建线程 默认情况下,仅在新任务到达时创建和启动线程,即便是核心线程。可以使用prestartCoreThread或者prestartAllCoreThreads对此进行动态更改。...如果工作线程或者其它线程使用不具有该权限的线程池,服务可能被降级:配置变更可能不会及时生效,且关闭线程池可能会保留终止但未完成的状态。...拒绝处理任务 当Executor已关闭、使用有界的线程池、工作队列,且达到最大值时,通过方法execute(Runnable)提交的任务将被拒绝。...hook方法运行完成时。
当任务提交到线程池但线程池无法处理新任务(比如,因为已经关闭了或者达到了其最大容量)时,就会抛出此异常。...二、可能出错的原因 线程池已满且RejectedExecutionHandler的默认策略是抛出异常。 线程池已关闭,无法接受新任务。 提交的任务数量超过了线程池的最大处理能力。...,优雅地关闭线程池 executor.shutdown(); // 开始关闭过程,不再接受新任务 try { // 等待所有任务完成,...当线程池不能接受新任务时,它会尝试在调用execute的线程中运行该任务。 五、注意事项 在设计线程池时,要充分考虑系统的并发需求和资源限制,合理设置线程池的大小和队列容量。...对于需要长时间运行的任务,建议使用单独的线程或线程池来处理,避免阻塞核心线程池。 在使用线程池时,要注意优雅地关闭线程池,避免资源泄露。
线程池种类 newCachedThreadPool 用newCachedThreadPool()方法创建该线程池对象,创建之初里面一个线程都没有,当execute方法或submit方法向线程池提交任务时...线程池任务执行流程: 当线程池小于corePoolSize时,新任务将创建一个新的线程,即使此时线程池种存在空闲线程。...当workQueue已满,且maximumPoolSize>corePoolSize时,新任务会创建新线程执行任务。...当线程池中超过corePoolSize时,空闲时间达到keepAliveTime时,关闭空闲线程。...,关闭空闲线程 当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize线程空闲时间达到keepAliveTime也将关闭 ?
线程池的作用是维护一定数量的线程,并在需要时将任务提交给这些线程执行,避免了线程的频繁创建和销毁。 3....工作流程 ThreadPoolExecutor 的工作流程可以简单地描述如下: 当线程池接收到一个新任务时,首先检查核心线程是否已满,如果未满,则创建一个新的核心线程来执行该任务。...当线程池处于 SHUTDOWN 状态时,不再接受新任务,但会继续执行已有任务,直到任务队列为空。 当线程池处于 STOP 状态时,会立即停止所有正在执行的任务,并清空任务队列。...executor.submit(() -> { // 任务逻辑 }); 关闭线程池 当不再需要线程池时,应该调用 shutdown 方法来关闭线程池。...关闭线程池后,将不再接受新任务,但会继续执行已有任务,直到任务队列为空。
问题的产生 最近在开发批量发送动态push功能的时候,用了线程池提高批量发送的效率,并在线程池任务全部执行完毕后,更新MySQL数据库里接收人的状态信息为已接收状态。...,我们使用ThreadPoolExecutor类创建了一个数量为3的线程池来执行任务,在这3个线程执行任务被占用期间,如果有新任务提交给线程池,那么这些新任务会被保存在BlockingQueue阻塞队列里...一般调用shutdown()方法之后,JVM会得到一个关闭线程池的信号,并不会立即关闭线程池,原来线程池里未执行完的任务仍然在执行,等到任务都执行完后才关闭线程池,但是JVM不允许再提交新任务给线程池。...executor.execute(tasks[0]);// 关闭线程池之后提交新任务,运行之后抛异常 } } 运行一下,看到如下输出: pool-1-thread-1 执行任务 0 pool-1...当等待任务的数量超过线程池阻塞队列的最大容量时,抛出了RejectedExecutionException异常。
newCachedThreadPool:将创建一个可缓存的线程池,如果线程池的当前规模超过了处理需求时,那么将回收空闲的线程,而当需求增加时,可以添加新的线程。...newScheduledThreadPool:创建一个固定长度的线程池,而且以延迟或定时的方式来执行任务。...平缓关闭模式:完成所有已启动的任务,并且不再接收新任务 暴力关闭模式:直接关掉电源 为了解决执行服务的生命周期问题,Executor扩展了ExecutorService接口,添加了一些用于生命周期管理的方法...ExecutorService 的生命周期有三种状态:运行、关闭和已终止。ExecutorService 在初始创建时处于运行状态。...Public interface ExecutorService extends Excutor{ void shutdown(); //执行平缓关闭过程----不再接收新任务,同时等待已提交任务的完成
extends Callable> tasks) throws InterruptedException; /** * 执行给定的任务,当所有任务完成或超时期满时...):当提交一个任务到线程池时,线程会创建一个线程来执行任务,即使其他空闲的基本线程能创建线程也会创建线程,等到到需要执行的任务数大于线程池基本大小corePoolSize时就不再创建 。...当队列和线程池都满了,说明线程池处于饱和状态,那么必须采取一种策略处理提交的新任务。这个策略默认情况下是AbortPolicy,表示无法处理新任务时抛出异常。...corePoolSize(即当前线程池中午运行的线程),则创建一个新的线程来执行任务 2,当线程池中有一个运行的线程时,将任务加入阻塞队列 3,当线程完成任务时,会无限反复从链式阻塞队列中获取任务来执行...总结:线程池优先要创建出基本线程池大小(corePoolSize)的线程数量,没有达到这个数量时,每次提交新任务都会直接创建一个新线程,当达到了基本线程数量后,又有新任务到达,优先放入等待队列,如果队列满了
当线程数小于该值时,线程池会优先创建新线程来执行新任务 maximumPoolSize 线程池所能维护的最大线程数 keepAliveTime 空闲线程的存活时间 workQueue 任务队列,用于缓存未执行的任务...可通过工厂为新建的线程设置更有意义的名字 handler 拒绝策略。当线程池和任务队列均处于饱和状态时,使用拒绝策略处理新任务。...3.1.4 排队策略 如3.1.2 线程创建规则一节中规则2所说,当线程数量大于等于 corePoolSize,workQueue 未满时,则缓存新任务。...3.2 重要操作 3.2.1 线程的创建与复用 在线程池的实现上,线程的创建是通过线程工厂接口ThreadFactory的实现类来完成的。...调用 shutdown 和 shutdownNow 方法关闭线程池后,就不能再向线程池提交新任务了。对于处于关闭状态的线程池,会使用拒绝策略处理新提交的任务。
标记3尝试终止线程池,后续会研究。 标记4处理线程池还是RUNNING或SHUTDOWN状态时,如果worker是异常结束,那么会直接addWorker。...总结一下worker:线程池启动后,worker在池内创建,包装了提交的Runnable任务并执行,执行完就等待下一个任务,不再需要时就结束。...线程池的关闭 线程池的关闭不是一关了事,worker在池里处于不同状态,必须安排好worker的”后事”,才能真正释放线程池。...,你可能疑惑在shutdown时已经调用过了,为什么又调用,而且每次只中断一个空闲worker?...每次只中断一个是因为processWorkerExit时,还会执行tryTerminate,自动中断下一个空闲的worker。 标记3是最终的状态切换。
此时一旦有worker完成手头的任务就会到workQueue中领取一个新任务继续执行。...队列中元素需要实现Comparable接口或初始化队列时传入一个Comparator对象。...5.threadFactory 每当线程池需要创建一个线程时,都是通过线程工厂方法来完成。默认的线程工厂方法将创建一个新的、非守护的线程,并且不包含特殊配置信息。...STOP -> TIDYING:线程池为空时 TIDYING -> TERMINATED:调用terminated()后 关闭线程池方法 shutdown():不再接受新任务,同时已提交的任务执行完成...线程的创建时机 提交任务时被创建(即客户端调用submit方法)。不过提交任务未必一定会创建线程,这在前面线程池的工作流程里已经提到。 预先启动线程池中核心线程池。
领取专属 10元无门槛券
手把手带您无忧上云