三语网站建设wordpress需要开什么端口
- 作者: 五速梦信息网
- 时间: 2026年03月21日 09:47
当前位置: 首页 > news >正文
三语网站建设,wordpress需要开什么端口,网站排名易下拉霸屏,金坛做网站的Java面试知识点(全) 导航#xff1a; https://nanxiang.blog.csdn.net/article/details/130640392 注#xff1a;随时更新
Spring 事物 事务简介#xff1a; 事务管理是企业级应用程序开发中必不可少的技术#xff0c;用来确保数据的完整性和一致性 事务就是一系列的动作 https://nanxiang.blog.csdn.net/article/details/130640392 注随时更新
Spring 事物 事务简介 事务管理是企业级应用程序开发中必不可少的技术用来确保数据的完整性和一致性 事务就是一系列的动作它们被当作一个单独的工作单元。这些动作要么全部完成要么全部不起作用 事务的四个关键属性(ACID) ① 原子性(atomicity):事务是一个原子操作有一系列动作组成。事务的原子性确保动作要么全部完成要么完全不起作用 ② 一致性(consistency):一旦所有事务动作完成事务就被提交。数据和资源就处于一种满足业务规则的一致性状态中 ③ 隔离性(isolation):可能有许多事务会同时处理相同的数据因此每个事物都应该与其他事务隔离开来防止数据损坏 ④ 持久性(durability):一旦事务完成无论发生什么系统错误它的结果都不应该受到影响。通常情况下事务的结果被写到持久化存储器中 Spring中的事务管理 作为企业级应用程序框架Spring在不同的事务管理API之上定义了一个抽象层。而应用程序开发人员不必了解底层的事务管理API就可以使用Spring的事务管理机制。 Spring既支持编程式事务管理(也称编码式事务)也支持声明式的事务管理 编程式事务管理将事务管理代码嵌入到业务方法中来控制事务的提交和回滚在编程式事务中必须在每个业务操作中包含额外的事务管理代码 声明式事务管理大多数情况下比编程式事务管理更好用。它将事务管理代码从业务方法中分离出来以声明的方式来实现事务管理。事务管理作为一种横切关注点可以通过AOP方法模块化。Spring通过Spring AOP框架支持声明式事务管理。 Spring的事务管理器 Spring并不直接管理事务而是提供了多种事务管理器它们将事务管理的职责委托给JTA或其他持久化机制所提供的平台相关的事务实现。每个事务管理器都会充当某一特定平台的事务实现的门面这使得用户在Spring中使用事务时几乎不用关注实际的事务实现是什么。
Spring提供了许多内置事务管理器实现
DataSourceTransactionManager位于org.springframework.jdbc.datasource包中数据源事务管理器提供对单个javax.sql.DataSource事务管理用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理JdoTransactionManager位于org.springframework.orm.jdo包中提供对单个javax.jdo.PersistenceManagerFactory事务管理用于集成JDO框架时的事务管理JpaTransactionManager位于org.springframework.orm.jpa包中提供对单个javax.persistence.EntityManagerFactory事务支持用于集成JPA实现框架时的事务管理HibernateTransactionManager位于org.springframework.orm.hibernate3包中提供对单个org.hibernate.SessionFactory事务支持用于集成Hibernate框架时的事务管理该事务管理器只支持Hibernate3版本且Spring3.0版本只支持Hibernate 3.2版本JtaTransactionManager位于org.springframework.transaction.jta包中提供对分布式事务管理的支持并将事务管理委托给Java EE应用服务器事务管理器OC4JjtaTransactionManager位于org.springframework.transaction.jta包中Spring提供的对OC4J10.1.3应用服务器事务管理器的适配器此适配器用于对应用服务器提供的高级事务的支持WebSphereUowTransactionManager位于org.springframework.transaction.jta包中Spring提供的对WebSphere 6.0应用服务器事务管理器的适配器此适配器用于对应用服务器提供的高级事务的支持WebLogicJtaTransactionManager位于org.springframework.transaction.jta包中Spring提供的对WebLogic 8.1应用服务器事务管理器的适配器此适配器用于对应用服务器提供的高级事务的支持。
TransactionDefinition 事务定义信息隔离、传播、超时、只读
脏读一个事务读取了另一个事务改写但还未提交的数据如果这些数据被回滚则读到的数据是无效的。 不可重复读在同一事务中多次读取同一数据返回的结果有所不同。 幻读一个事务读取了几行记录后另一个事务插入一些记录幻读就发生了。再后来的查询中第一个事务就会发现有些原来没有的记录。
事务隔离级别五种
DEFAULT–使用后端数据库默认的隔离级别Spring中的选择项 READ_UNCOMMITED–允许你读取还未提交的改变了的数据。可能导致脏、幻、不可重复读 READ_COMMITTED–允许在并发事务已经提交后读取。可防止脏读但幻读和不可重复读仍可发生 REPEATABLE_READ–对相同字段的多次读取是一致的除非数据被事务本身改变。可防止脏、不可重复读但幻读仍可能发生 SERIALIZABLE–完全服从ACID的隔离级别确保不发生脏、幻、不可重复读。这在所有的隔离级别中是最慢的它是典型的通过完全锁定在事务中涉及的数据表来完成的 其中MySQL默认采用REPEATABLE_READ隔离级别Oracle默认采用READ_COMMITTED隔离级别
事务传播行为七种
REQUIRED–支持当前事务如果当前没有事务就新建一个事务。这是最常见的选择。 SUPPORTS–支持当前事务如果当前没有事务就以非事务方式执行。 MANDATORY–支持当前事务如果当前没有事务就抛出异常。 REQUIRES_NEW–新建事务如果当前存在事务把当前事务挂起。 NOT_SUPPORTED–以非事务方式执行操作如果当前存在事务就把当前事务挂起。 NEVER–以非事务方式执行如果当前存在事务则抛出异常。 NESTED–如果当前存在事务则在嵌套事务内执行。如果当前没有事务则进行与REQUIRED类似的操作。拥有多个可以回滚的保存点内部回滚不会对外部事务产生影响。只对DataSourceTransactionManager有效
Spring事务的只读
“只读事务”并不是一个强制选项它只是一个“暗示”提示数据库驱动程序和数据库系统这个事务并不包含更改数据的操作那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化比方说不安排相应的数据库锁以减轻事务 对数据库的压力毕竟事务也是要消耗数据库的资源的。“只读事务”仅仅是一个性能优化的推荐配置而已并非强制你要这样做不可。
Spring事务的事务超时
为了使应用程序更好的运行事务不能运行太长的时间。因此声明式事务的第四个特性就是超时。
Spring事务的回滚规则
默认情况下事务只有在遇到运行期异常时才会回滚而在遇到检查型异常时不会回滚但是也可以声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。同样你还可以声明事务遇到特定的异常不回滚即使这些异常是运行期异常
数据库锁
【为什么要锁】
数据库是一个多用户使用的共享资源,比如一个用户表t_user,两个浏览器前面的人登录了同个一个账号把电话号码改了。当多个用户并发地存取数据时在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据破坏数据库的一致性(脏读不可重复读幻读等)可能产生死锁。为了解决这个问题加锁是一个非常重要的技术对实现数据库并发控制是一个好的方案。简单说当一个执行sql语句的事务想要操作表记录之前先向数据库发出请求对你访问的记录集加锁在这个事务释放这个锁之前其他事务不能对这些数据进行更新操作。
【有哪些锁】
锁包括行级锁、表级锁、悲观锁、乐观锁 行级锁: 一种它锁防止另外事务修改此行;在使用以下语句时Oracle会自动应用行级锁INSERT、UPDATE、DELETE、SELECT … FOR UPDATE [OF columns] [WAIT n | NOWAIT];SELECT… FOR UPDATE语句允许用户一次锁定多条记录进行更新.使用commit或者rollback释放锁。MySql的innodb存储引擎默认是行级锁。特点:开锁大加锁慢会出现死锁锁定粒度最小发生锁冲突的概率最低并发度也最高。适合于有大量按索引更新少量不同数据同时又有并发查询的应用如一些在线事务处理系统。 表级锁:5种 行共享 (ROW SHARE) – 禁止排他锁定表与行排他类似区别是别的事务还可以在此表上加任何排他锁。除排他exclusive外
行排他(ROW EXCLUSIVE) – 禁止使用排他锁和共享锁其他事务依然可以并发地对相同数据表执行查询插入更新删除操作或对表内数据行加锁的操作但不能有其他的排他锁自身是可以的没发现有什么用
共享锁(SHARE) - 锁定表对记录只读不写多个用户可以同时在同一个表上应用此锁在表没有被任何DML操作时多个事务都可加锁但只有在仅一个事务加锁的情况下只有此事务才能对表更新当表已经被更新或者指定要更新时select for update任何事务都不能加此锁了。
共享行排他(SHARE ROW EXCLUSIVE) – 比共享锁更多的限制禁止使用共享锁及更高的锁在表没有被任何DML操作时只有一个事务可以加锁可以更新书上说别的事务可以使用select for update锁定选中的数据行可是实验后没被验证。 排他(EXCLUSIVE) –限制最强的表锁仅允许其他用户查询该表的行。禁止修改和锁定表
行级锁和表级锁是根据锁的粒度来区分的行记录表都是资源锁是作用在这些资源上的。如果粒度比较小(比如行级锁)可以增加系统的并发量但需要较大的系统开销会影响到性能出现死锁因为粒度小则操作的锁的数量会增加;如果作用在表上粒度大开销小维护的锁少不会出现死锁但是并发是相当昂贵的因为锁定了整个表就限制了其它事务对这个表中其他记录的访问。
悲观锁:
Pessimistic Lock正如其名它指的是对数据被外界包括本系统当前的其他事务以及来自外部系统的事务处理修改持保守悲观态度事务每次去操作数据的时候都假设有其他事务会修改需要访问的数据所以在访问之前都要求上锁行锁表锁等读锁写锁等都是在做操作之前先上锁因此在整个数据处理过程中将数据处于锁定状态。悲观锁的实现往往依靠数据库提供的锁机制也只有数据库层提供的锁机制才能 真正保证数据访问的排他性否则即使在本系统中实现了加锁机制也无法保证外部系 统不会修改数据。 一个典型的倚赖数据库的悲观锁调用 select * from account where name”Erica” for update 这条sql 语句锁定了account 表中所有符合检索条件name”Erica”的记录。 本次事务提交之前事务提交时会释放事务过程中的锁外界无法修改这些记录。
乐观锁:
Optimistic Lock,和悲欢锁相反事务每次去操作数据之前都假设其他事务不会修改这些需要访问的数据 所以 在访问之前不要求上锁只是在进行更新修改操作的时候判断一下在访问的期间有没有其他人修改数据 了。它适用于多读的应用类型冲突真的发生比较少的时候就比较好这样省去了开销的开销可以提高吞吐量;但如果是真的经常要发生冲突的那每次还要去判断进行retry,反倒降低的性能这个时候悲欢锁比较好。数据库如果提供类似于write_condition机制的其实都是提供的乐观锁。 它的实现大多是基于数据版本version记录机制。举个例子: 1.利润表t_profit中有一个 version字段当前值为1而总资产余额字段balance为$10000 2.操作员A读出version1,从总资产减除200010000-20008000. 3.A还没操作结束此时操作员B也读出version1,总资产减除500010000-50005000. 4.A操作完成把version加1修改为2把总资产减2000后提交更新数据库更新成功 5.B操作了也加version加1修改为2把总资产减5000后提交更新数据库此时发现version已经为2了如B修改后加1的version一样不满足乐观锁策略:“提交的版本必有大于记录当前的版本才能执行”。因此B的操作请求被驳回这样就避免了B就version1的旧数据修改的结果覆盖了A操作的结果的可能。如没有乐观锁那A减去2000后剩余8000但B操作的时候是用10000-5000剩余5000的如果B的提交成功总资产余额就是5000但实际情况应该是8000-50003000的。出现总资产表记录和实际支出不一致。
ThreadLocal
我们知道Spring通过各种DAO模板类降低了开发者使用各种数据持久技术的难度。这些模板类都是线程安全的也就是说多个DAO可以复用同一个模板实例而不会发生冲突。 我们使用模板类访问底层数据根据持久化技术的不同模板类需要绑定数据连接或会话的资源。但这些资源本身是非线程安全的也就是说它们不能在同一时刻被多个线程共享。
虽然模板类通过资源池获取数据连接或会话但资源池本身解决的是数据连接或会话的缓存问题并非数据连接或会话的线程安全问题。
按照传统经验如果某个对象是非线程安全的在多线程环境下对对象的访问必须采用synchronized进行线程同步。但Spring的DAO模板类并未采用线程同步机制因为线程同步限制了并发访问会带来很大的性能损失。
此外通过代码同步解决性能安全问题挑战性很大可能会增强好几倍的实现难度。那模板类究竟仰丈何种魔法神功可以在无需同步的情况下就化解线程安全的难题呢答案就是ThreadLocal
ThreadLocal在Spring中发挥着重要的作用在管理request作用域的Bean、事务管理、任务调度、AOP等模块都出现了它们的身影起着举足轻重的作用。要想了解Spring事务管理的底层技术ThreadLocal是必须攻克的山头堡垒。
ThreadLocal是什么
早在JDK1.2的版本中就提供java.lang.ThreadLocalThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ThreadLocal很容易让人望文生义想当然地认为是一个“本地线程”。其实ThreadLocal并不是一个Thread而是Thread的局部变量也许把它命名为ThreadLocalVariable更容易让人理解一些。 当使用ThreadLocal维护变量时ThreadLocal为每个使用该变量的线程提供独立的变量副本所以每一个线程都可以独立地改变自己的副本而不会影响其它线程所对应的副本。
从线程的角度看目标变量就象是线程的本地变量这也是类名中“Local”所要表达的意思。 线程局部变量并不是Java的新发明很多语言如IBM IBM XLFORTRAN在语法层面就提供线程局部变量。在Java中没有提供在语言级支持而是变相地通过ThreadLocal的类提供支持。 所以在Java中编写线程局部变量的代码相对来说要笨拙一些因此造成线程局部变量没有在Java开发者中得到很好的普及。
ThreadLocal的接口方法
ThreadLocal类接口很简单只有4个方法我们先来了解一下 void set(Object value) 设置当前线程的线程局部变量的值。 public Object get() 该方法返回当前线程所对应的线程局部变量。 public void remove() 将当前线程局部变量的值删除目的是为了减少内存的占用该方法是JDK5.0新增的方法。需要指出的是当线程结束后对应该线程的局部变量将自动被垃圾回收所以显式调用该方法清除线程的局部变量并不是必须的操作但它可以加快内存回收的速度。 protected Object initialValue() 返回该线程局部变量的初始值该方法是一个protected的方法显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法在线程第1次调用get()或set(Object)时才执行并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。 值得一提的是在JDK5.0中ThreadLocal已经支持泛型该类的类名已经变为ThreadLocal。API方法也相应进行了调整新版本的API方法分别是voidset(T value)、T get()以及T initialValue()。 ThreadLocal是如何做到为每一个线程维护变量的副本的呢其实实现的思路很简单在ThreadLocal类中有一个Map用于存储每一个线程的变量副本Map中元素的键为线程对象而值对应线程的变量副本。我们自己就可以提供一个简单的实现版本 //SimpleThreadLocalclass SimpleThreadLocal {private MapvalueMap Collections.synchronizedMap(new HashMap());public voidset(Object newValue) {valueMap.put(Thread.currentThread(), newValue);//①键为线程对象值为本线程的变量副本}publicObject get() {Thread currentThread Thread.currentThread();Object o valueMap.get(currentThread);// ②返回本线程对应的变量if (o null !valueMap.containsKey(currentThread)) {// ③如果在Map中不存在放到Map// 中保存起来。o initialValue();valueMap.put(currentThread, o);}return o;}public voidremove() {valueMap.remove(Thread.currentThread());}publicObject initialValue() {return null;}}虽然这个ThreadLocal实现版本显得比较幼稚但它和JDK所提供的ThreadLocal类在实现思路上是相近的。
一个TheadLocal实例 下面我们通过一个具体的实例了解一下ThreadLocal的具体使用方法
public class SequenceNumber {//①通过匿名内部类覆盖ThreadLocal的initialValue()方法指定初始值privatestatic ThreadLocalInteger seqNum new ThreadLocalInteger() {public Integer initialValue() {return 0;}};//②获取下一个序列值public intgetNextNum() {seqNum.set(seqNum.get() 1);return seqNum.get();}publicstatic void main(String[] args){SequenceNumber sn new SequenceNumber();// ③ 3个线程共享sn各自产生序列号TestClient t1 new TestClient(sn);TestClient t2 new TestClient(sn);TestClient t3 new TestClient(sn);t1.start();t2.start();t3.start();}privatestatic class TestClient extends Thread{private SequenceNumber sn;public TestClient(SequenceNumber sn) {this.sn sn;}public void run(){for (int i 0; i 3; i) {// ④每个线程打出3个序列值System.out.println(thread[ Thread.currentThread().getName()]sn[ sn.getNextNum() ]);}}}}通常我们通过匿名内部类的方式定义ThreadLocal的子类提供初始的变量值如例子中①处所示。TestClient线程产生一组序列号在③处我们生成3个TestClient它们共享同一个SequenceNumber实例。运行以上代码在控制台上输出以下的结果 thread[Thread-2] sn[1] thread[Thread-0] sn[1] thread[Thread-1] sn[1] thread[Thread-2] sn[2] thread[Thread-0] sn[2] thread[Thread-1] sn[2] thread[Thread-2] sn[3] thread[Thread-0] sn[3] thread[Thread-1] sn[3]
考察输出的结果信息我们发现每个线程所产生的序号虽然都共享同一个SequenceNumber实例但它们并没有发生相互干扰的情况而是各自产生独立的序列号这是因为我们通过ThreadLocal为每一个线程提供了单独的副本。
Thread同步机制的比较
ThreadLocal和线程同步机制相比有什么优势呢ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
在同步机制中通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的使用同步机制要求程序慎密地分析什么时候对变量进行读写什么时候需要锁定某个对象什么时候释放对象锁等繁杂的问题程序设计和编写难度相对较大。
而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本从而也就没有必要对该变量进行同步了。 ThreadLocal提供了线程安全的共享对象在编写多线程代码时可以把不安全的变量封装进ThreadLocal。
由于ThreadLocal中可以持有任何类型的对象低版本JDK所提供的get()返回的是Object对象需要强制类型转换。但JDK5.0通过泛型很好的解决了这个问题在一定程度地简化ThreadLocal的就使用了JDK5.0新的ThreadLocal版本。 概括起来说对于多线程资源共享的问题同步机制采用了“以时间换空间”的方式而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量让不同的线程排队访问而后者为每一个线程都提供了一份变量因此可以同时访问而互不影响。
Spring使用ThreadLocal解决线程安全问题
我们知道在一般情况下只有无状态的Bean才可以在多线程环境下共享在Spring中绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等中非线程安全状态采用ThreadLocal进行处理让它们也成为线程安全的状态因为有状态的Bean就可以在多线程中共享了。
一般的Web应用划分为展现层、服务层和持久层三个层次在不同的层中编写对应的逻辑下层通过接口向上层开放功能调用。在一般情况下从接收请求到返回响应所经过的所有程序调用都同属于一个线程
Spring TaskExecutor线程池
多线程并发处理起来通常比较麻烦如果你使用spring容器来管理业务bean事情就好办了多了。spring封装了Java的多线程的实现你只需要关注于并发事物的流程以及一些并发负载量等特性具体来说如何使用spring来处理并发事务 1.了解 TaskExecutor接口 Spring的TaskExecutor接口等同于java.util.concurrent.Executor接口。 实际上它存在的主要原因是为了在使用线程池的时候将对Java5的依赖抽象出来。 这个接口只有一个方法execute(Runnable task)它根据线程池的语义和配置来接受一个执行任务。最初创建TaskExecutor是为了在需要时给其他Spring组件提供一个线程池的抽象。 例如ApplicationEventMulticaster组件、JMS的 AbstractMessageListenerContainer和对Quartz的整合都使用了TaskExecutor抽象来提供线程池。 当然如果你的bean需要线程池行为你也可以使用这个抽象层。 TaskExecutor接口的实现类 (1)SimpleAsyncTaskExecutor 类 这个实现不重用任何线程或者说它每次调用都启动一个新线程。但是它还是支持对并发总数设限当超过线程并发总数限制时阻塞新的调用直到有位置被释放。如果你需要真正的池请继续往下看。 (2)SyncTaskExecutor类 这个实现不会异步执行。相反每次调用都在发起调用的线程中执行。它的主要用处是在不需要多线程的时候比如简单的test case。 (3)ConcurrentTaskExecutor 类 这个实现是对Java 5 java.util.concurrent.Executor类的包装。有另一个备选, ThreadPoolTaskExecutor类它暴露了Executor的配置参数作为bean属性。很少需要使用ConcurrentTaskExecutor, 但是如果ThreadPoolTaskExecutor不敷所需ConcurrentTaskExecutor是另外一个备选。 (4)SimpleThreadPoolTaskExecutor 类 这个实现实际上是Quartz的SimpleThreadPool类的子类它会监听Spring的生命周期回调。当你有线程池需要在Quartz和非Quartz组件中共用时这是它的典型用处。 (5)ThreadPoolTaskExecutor 类 它不支持任何对java.util.concurrent包的替换或者下行移植。Doug Lea和Dawid Kurzyniec对java.util.concurrent的实现都采用了不同的包结构导致它们无法正确运行。 这个实现只能在Java 5环境中使用但是却是这个环境中最常用的。它暴露的bean properties可以用来配置一个java.util.concurrent.ThreadPoolExecutor把它包装到一个TaskExecutor中。如果你需要更加先进的类比如ScheduledThreadPoolExecutor,我们建议你使用ConcurrentTaskExecutor来替代。 (6)TimerTaskExecutor类 这个实现使用一个TimerTask作为其背后的实现。它和SyncTaskExecutor的不同在于方法调用是在一个独立的线程中进行的虽然在那个线程中是同步的。 (7)WorkManagerTaskExecutor类 这个实现使用了CommonJ WorkManager作为其底层实现是在Spring context中配置CommonJ WorkManager应用的最重要的类。和SimpleThreadPoolTaskExecutor类似这个类实现了WorkManager接口因此可以直接作为WorkManager使用。
案例-注册TaskExecutor Configurationpublic class WebMvcConfigurerAdpter extends AbstractWebMvcConfigurerAdpter {Overridepublic void configureMessageConverters(ListHttpMessageConverter? converters) {super.configureMessageConverters(converters);WafJsonMapper.getMapper().enable(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS);}Beanpublic TaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);return executor;}}Servicepublic class TaskService {Autowiredprivate TaskExecutor executor;public void execute() {executor.execute(new Runnable() {Overridepublic void run() {for (int i 0; i 10; i) {try {Thread.sleep(1000);System.out.println(task running …);} catch (Exception e) {RestControllerRequestMapping(value /v0.1)public class TaskController {Autowiredprivate TaskService taskService;RequestMapping()public Object execute() {taskService.execute();Map res new HashMap();res.put(result, success);return res;}}程序不会等到10个线程都跑完才返回结果不是阻塞程序返回结果后线程仍然在执行。
案例 ThreadPoolTaskExecutor poolTaskExecutor new ThreadPoolTaskExecutor();
//线程池所使用的缓冲队列 poolTaskExecutor.setQueueCapacity(200); //线程池维护线程的最少数量 poolTaskExecutor.setCorePoolSize(5);
//线程池维护线程的最大数量
poolTaskExecutor.setMaxPoolSize(1000); //线程池维护线程所允许的空闲时间 poolTaskExecutor.setKeepAliveSeconds(30000); poolTaskExecutor.initialize(); 配置解释
当一个任务通过execute(Runnable)方法欲添加到线程池时 1、 如果此时线程池中的数量小于corePoolSize即使线程池中的线程都处于空闲状态也要创建新的线程来处理被添加的任务。 2、 如果此时线程池中的数量等于 corePoolSize但是缓冲队列 workQueue未满那么任务被放入缓冲队列。 3、如果此时线程池中的数量大于corePoolSize缓冲队列workQueue满并且线程池中的数量小于maximumPoolSize建新的线程来处理被添加的任务。 4、 如果此时线程池中的数量大于corePoolSize缓冲队列workQueue满并且线程池中的数量等于maximumPoolSize那么通过 handler所指定的策略来处理此任务。也就是处理任务的优先级为核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize如果三者都满了使用handler处理被拒绝的任务。 5、 当线程池中的线程数量大于 corePoolSize时如果某线程空闲时间超过keepAliveTime线程将被终止。这样线程池可以动态的调整池中的线程数。
xml配置使用 !– 配置线程池 – bean id taskExecutor class org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor !– 线程池维护线程的最少数量 – span stylewhite-space:pre /spanproperty name corePoolSize value 5 / !– 线程池维护线程所允许的空闲时间 – span stylewhite-space:pre /spanproperty name keepAliveSeconds value 30000 / !– 线程池维护线程的最大数量 – span stylewhite-space:pre /spanproperty name maxPoolSize value 1000 / !– 线程池所使用的缓冲队列 – span stylewhite-space:pre /spanproperty name queueCapacity value 200 / /bean ApplicationContext ctx new ClassPathXmlApplicationContext(applicationContext.xml);ThreadPoolTaskExecutor poolTaskExecutor (ThreadPoolTaskExecutor)ctx.getBean(taskExecutor);Thread udpThread new Thread(udp);poolTaskExecutor.execute(udpThread);获取当前线程池活动的线程数int count poolTaskExecutor.getActiveCount();logger.debug([x] - now threadpool active threads totalNum : count);
外传 原创不易如若本文能够帮助到您的同学支持我关注我点赞收藏⭐️留言探讨问题看到立马回复格言己所不欲勿施于人 扬帆起航、游历人生、永不言弃
- 上一篇: 三亚网站建设价格阳江网红景点
- 下一篇: 三原做网站石家庄网页设计制作






