性能测试(九)连接池和线程

之前的博客中,有说的性能测试常见术语:连接池。其中大概简述了连接池的作用等,这篇博客,就介绍下连接池以及连接池中线程对象的原理,作用以及优点。。。

一、连接池

1、什么是连接池?我们为什么需要它?

连接池允许多个客户端使用缓存起来的连接对象,这些对象可以连接数据库,它们是共享的、可被重复使用的。

打开/关闭数据库连接开销很大,连接池技术允许我们在连接池里维护连接对象,这样可以提高数据库的执行命令的性能。多个客户端请求可以重复使用相同的连接对象,当每次收到一个客户端请求时,

就会搜索连接池,看看有没有闲置连接对象。如果没有,要么所有的客户端请求都进入队列排队,要么在池中创建一个新的连接对象(这取决于池里已有多少个连接存在以及配置支持多少连接)。

一旦某个请求使用完连接对象之后,这个对象会被重新放入池中,然后会被重新分派给排队等待的请求(分派给哪个请求要看使用什么调度算法)。

因为大部分请求都是使用现存的连接对象,所以连接池技术大大减少了等待创建数据库连接的时间,从而减少了平均连接时间。

2、如何使用连接池?

连接池在基于网络的企业级应用中很常见,应用服务器负责创建连接对象、添加它们到连接池中,分派连接对象给请求,回收使用完毕的连接对象,重新将它们放回连接池去。

当网络应用创建数据库连接时,应用服务器会从池中取出连接对象,而当它使用完毕之后关闭时,应用服务器又负责将使用完的连接对象放回池中。

PS:也可以使用JDBC 1.0/JDBC 2.0 API来获取物理连接(physical connnection),但这种情况非常少见,因为数据库只需要连接一次,不需要连接池的情况。

3、连接池可以处理多少连接?谁创建/释放连接?

可以进行配置最大的连接数、最小连接数、最大空闲连接数等,所有这些参数都可以由服务器管理员配置。服务器启动时,固定数量的连接对象(配置的最小连接数)被创建,并添加到连接池中。

当客户端请求消耗完所有的连接对象时,再有新的请求都会创建新的连接对象,它们被添加到连接池再分派给这个新的请求,直到设置的达到最大的连接数。

服务器也会一直查看闲置的连接对象数,当检测到闲置的连接数超过设置值时,服务器会关闭闲置连接,然后它们将被垃圾回收。

4、传统的连接池 vs 可管理的连接池

连接池是个开放的概念,任何应用都可以使用这个概念,并用自己想要的方式管理它。连接池概念指的是创建、管理、维护连接对象。

但当应用的规模增大时,如果没有一个健壮的连接池机制的话,管理连接是会得越来越困难。

因此,建立一个健壮的、可管理的连接池很有必要。

PS:关于连接池的内容,参考自http://www.importnew.com/8179.html

二、线程&线程池,连接&连接池

线程:程序执行流的最小单元,进程中的一个实体,一个相对独立的、可调度的执行单元,是被系统独立调度和分派的基本单位;

多线程技术,指在一个进程当中可以创建多个线程来“同时”处理多个事务;

线程池:可以理解为缓冲区,由于频繁的创建销毁线程会带来一定的成本,可以预先创建,但不立即销毁,以共享方式为别人提供服务,一来可以提供效率,再者可以控制线程无线扩张。

连接:指一点与另一点的连接;

连接池:跟线程池有同样的妙处,但连接池可以是基于多线程来实现,也可以通过多进程来实现,也可能是单实例的。

举个例子:

Socket在做为服务时,可以同时监听多个客户端连接,那么它的实现原理就有点像“连接池”;每个客户通过多个端口同时向服务器发送数据,可以认为是多线程,

而服务器可能已经建立好了n个线程来等待同时处理/分析客户端发来的数据,可以为是有个“线程池”。

三、线程的几种状态

线程在一定条件下,状态会发生变化。线程一共有以下几种状态:

1、新建状态(New):新创建了一个线程对象。

2、就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于“可运行线程池”中,变得可运行,只等待获取CPU的使用权,

即在就绪状态的进程除CPU之外,其它的运行所需资源都已全部获得。

3、运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。

4、阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。

阻塞的情况分三种:

①.等待阻塞:运行的线程执行wait()方法,该线程会释放占用的所有资源,JVM会把该线程放入“等待池”中。进入这个状态后,是不能自动唤醒的,

必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒,

②.同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入“锁池”中。

③.其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时,

或者I/O处理完毕时,线程重新转入就绪状态。

5、死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

线程变化的状态转换图如下:

PS:拿到对象的锁标记,即为获得了对该对象(临界区)的使用权限。即该线程获得了运行所需的资源,进入“就绪状态”,只需获得CPU,就可以运行。

因为当调用wait()后,线程会释放掉它所占有的“锁标志”,所以线程只有在此获取资源才能进入就绪状态。

下面作下解释:

①.线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,但不管怎样,  当我们new了这个对象后,线程就进入了初始状态;

②.当该对象调用了start()方法,就进入就绪状态;

③.进入就绪后,当该对象被操作系统选中,获得CPU时间片就会进入运行状态;

④.进入运行状态后情况就比较复杂;

(1)run()方法或main()方法结束后,线程就进入终止状态;

(2)当线程调用了自身的sleep()方法或其他线程的join()方法,进程让出CPU,然后就会进入阻塞状态(该状态既停止当前线程,但并不释放所占有的资源,

即调用sleep()函数后,线程不会释放它的“锁标志”。)。当sleep()结束或join()结束后,该线程进入可运行状态,继续等待OS分配CPU时间片;

典型地,sleep()被用在等待某个资源就绪的情形;测试发现条件不满足后,让线程阻塞一段时间后重新测试,直到条件满足为止。

(3)线程调用了yield()方法,意思是放弃当前获得的CPU时间片,回到就绪状态,这时与其他进程处于同等竞争状态,OS有可能会接着又让这个进程进入运行状态;

调用 yield() 的效果等价于调度程序认为该线程已执行了足够的时间片从而需要转到另一个线程。yield()只是使当前线程重新回到可执行状态,

所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

(4)当线程刚进入可运行状态(注意,还没运行),发现将要调用的资源被synchroniza(同步),获取不到锁标记,将会立即进入锁池状态,等待获取锁标记

(这时的锁池里也许已经有了其他线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程获得锁标记后,就转入就绪状态,等待OS分配CPU时间片。

(5)suspend() 和 resume()方法:两个方法配套使用,suspend()使得线程进入阻塞状态,并且不会自动恢复,必须其对应的resume()被调用,才能使得线程重新进入可执行状态。

典型地,suspend()和 resume() 被用在等待另一个线程产生的结果的情形:测试发现结果还没有产生后,让线程阻塞,另一个线程产生了结果后,调用resume()使其恢复。

(6)wait()和 notify() 方法:当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的所有资源,与阻塞状态不同),进入这个状态后,是不能自动唤醒的,

必须依靠其他线程调用notify()或notifyAll()方法才能被唤醒(由于notify()只是唤醒一个线程,但我们由不能确定具体唤醒的是哪一个线程,也许我们需要唤醒的线程不能够被唤醒,

因此在实际使用时,一般都用notifyAll()方法,唤醒有所线程),线程被唤醒后会进入锁池,等待获取锁标记。

wait() 使得线程进入阻塞状态,它有两种形式:

一种允许指定以ms为单位的时间作为参数,另一种没有参数。前者当对应的notify()被调用或超出指定时间时线程重新进入可执行状态即就绪状态,后者则必须对应的notify()被调用。

当调用wait()后,线程会释放掉它所占有的“锁标志”,从而使线程所在对象中的其它synchronized数据可被别的线程使用。

waite()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数或synchronizedblock中进行调用。

如果在non-synchronized函数或non-synchronizedblock中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。

PS:关于线程的几种状态,转载自开源中国:线程的几种状态

 

时间: 2024-10-25 21:00:24

性能测试(九)连接池和线程的相关文章

转 聊聊连接池和线程

https://www.cnblogs.com/imyalost/p/7189455.html 之前的博客中,有说到性能测试常见术语:连接池.其中大概简述了连接池的作用等,这篇博客,就介绍下连接池以及连接池中线程对象的原理,作用以及优点... 一.连接池 1.什么是连接池?我们为什么需要它? 连接池允许多个客户端使用缓存起来的连接对象,这些对象可以连接数据库,它们是共享的.可被重复使用的. 打开/关闭数据库连接开销很大,连接池技术允许我们在连接池里维护连接对象,这样可以提高数据库的执行命令的性能

连接池、线程池、定时任务、应用启动

/* 启动一个java app或者服务 */ import org.eclipse.jetty.server.Server; public class QuartzTest { /** *//** * @param args */ public static void main(String[] args) throws Exception { Server server = new Server(8899); server.setHandler(new ScheduleRouteHandle(

聊聊连接池和线程

一.连接池 1.什么是连接池?我们为什么需要它? 连接池允许多个客户端使用缓存起来的连接对象,这些对象可以连接数据库,它们是共享的.可被重复使用的. 打开/关闭数据库连接开销很大,连接池技术允许我们在连接池里维护连接对象,这样可以提高数据库的执行命令的性能.多个客户端请求可以重复使用相同的连接对象,当每次收到一个客户端请求时, 就会搜索连接池,看看有没有闲置连接对象.如果没有,要么所有的客户端请求都进入队列排队,要么在池中创建一个新的连接对象(这取决于池里已有多少个连接存在以及配置支持多少连接)

性能测试:连接池不释放

最近的性能测试中,遇到一个数据库连接池不释放的问题,下面描述下定位到这个问题的流程. 我们用的是dubbo框架 1.首先,压测过程中,请求失败了,所以,赶紧去看provider服务器日志(tail -f -n500 xxx.log),抛出的错误是: 2.原来是没获取到数据库的连接池,马上去看了下配置文件(less db.properties,最大连接数配置的100,此时并发的150),首先想到的是连接数配置的小了,于是改为150,当然,这个需要比数据库自身允许的连接数小,显示数据库最大连接数:s

mysql线程池与连接池

线程池与连接池 连接池通常实现在Client端,是指应用(客户端)创建预先创建一定的连接,利用这些连接服务于客户端所有的DB请求.如果某一个时刻,空闲的连接数小于DB的请求数,则需要将请求排队,等待空闲连接处理.通过连接池可以复用连接,避免连接的频繁创建和释放,从而减少请求的平均响应时间,并且在请求繁忙时,通过请求排队,可以缓冲应用对DB的冲击.线程池实现在server端,通过创建一定数量的线程服务DB请求,相对于one-conection-per-thread的一个线程服务一个连接的方式,线程

Mysql线程池系列一:什么是线程池和连接池( thread_pool 和 connection_pool)

   thread_pool 和 connection_pool 当客户端请求的数据量比较大的时候,使用线程池可以节约大量的系统资源,使得更多的CPU时间和内存可以高效地利用起来.而数据库连接池的使用则将大大提高程序运行效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量.使用情况等.本文我们主要就介绍一下线程池和数据库连接池的原理,接下来我们一起来了解一下这一部分内容. 首先介绍什么是mysql thread pool,干什么用的?使用线程池主要可以达到以下两个目的:1.在大并发的时

缓冲池,线程池,连接池

SSH:[email protected]:unbelievableme/object-pool.git   HTTPS:https://github.com/unbelievableme/object-pool.git 缓冲池 设计要点:包含三个队列:空缓冲队列(emq),装满输入数据的输入的队列(inq),装满输出数据的输出队列(outq),输入程序包括收容输入(hin),提取输入(sin),输出程序包括收容输出(hout)和提取输出(sout). 注意点:输入程序和输出程序会对缓冲区并发访

基于线程池和连接池的Http请求

背景:最新项目需求调用http接口,所以打算使用最新的httpClient客户端写一个工具类,写好了以后在实际应用过程中遇到了一些问题,因为数据量还算 大,每次处理大概要处理600-700次请求,平均算下来大概需要20分钟,这个速度虽然是跑在定时任务中的,但是也是不能忍受的,所以有了这个博客. 1.首先想到的解决办法就是多线程发请求了,但是这个有坑,最后会在结果处说明. 2.代码方面如下 ExecutorService executor = Executors.newFixedThreadPoo

(转)WebSphere 中池资源调优 - 线程池、连接池和 ORB

WebSphere 中池资源调优 - 线程池.连接池和 ORB 来自:https://www.ibm.com/developerworks/cn/websphere/library/techarticles/1106_zhuxl_websphereenhancement/1106_zhuxl_websphereenhancement.html IBM WebSphere Application Server (以下简称 WAS)能支持的应用程序越来越多,而这些应用程序有各自的独特特性.需求和服务