CountDownLatch和CyclicBarrier模拟同时并发请求

  

有时候要测试一下某个功能的并发能力,又不要想借助于其他测试工具,索性就自己写简单的演示模拟一个并发请求就最方便了。如果熟悉jemter的测试某接口的并发能力其实更专业,此处只是自己折腾着玩。

  

CountDownLatch和CyclicBarrier是jdk并发包下非常有用的两个并发工具类,它们提供了一种控制并发流程的手段,其实查看源码它们都是在内部维护了一个计数器控制流程的

  

CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行;
CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。
CountDownLatch和CyclicBarrier的区别

  

CountDownLatch的计数器,线程完成一个记录一个,计数器是递减计数器,只能使用一次
CyclicBarrier的计数器更像是一个阀门,需要所有线程都到达,阀门才能打开,然后继续执行,计数器是递增计数器提供重置功能,可以多次使用
另外信号可以控同时访问的线程个数,通过收购()获取一个许可,如果没有就等待,而释放()释放一个许可。

  

通常我们模拟并发请求,一般都是多开几个线程,发起请求就好了。但是方式,一般会存在启动的先后顺序了,算不得真正的同时并发!怎么样才能做到真正的同时并发呢?是本文想说的点,java中提供了闭锁CountDownLatch, CyclicBarrier刚好就用来做这种事就最合适了。

  

下面分别使用CountDownLatch和CyclicBarrier来模拟并发的请求

  

CountDownLatch模拟   

  

包com.test;      

进口java.io.BufferedReader;
进口java.io.IOException;
进口java.io.InputStream;
进口java.io.InputStreamReader;
进口java.io.OutputStream;
进口java.net.HttpURLConnection;
进口java.net.MalformedURLException;
进口java.net.URL;
进口java.util.concurrent.CountDownLatch;

  公共类LatchTest {

  
 <代码>公共静态void main (String [] args)抛出InterruptedException {
  Runnable taskTemp=new Runnable(){ 
  

//注意,此处是非线程安全的,留坑私人int iCounter;

  
 <代码> @Override
  公共空间run () {
  for (int i=0;我& lt;10;我+ +){//发起请求 
  

//HttpClientOp.doGet (“https://www.baidu.com/");
iCounter + +;
System.out.println (system . nanotime () +“;[“;+ Thread.currentThread () . getname () +“] iCounter=?+ iCounter),
{
thread . sleep (100),
}捕捉(InterruptedException e) {
e.printStackTrace ();
}
}
}
};

  
 <代码> LatchTest LatchTest=new LatchTest ();
  latchTest。taskTemp startTaskAllInOnce(5日);
  }
  
  公共长startTaskAllInOnce (int threadNums最终Runnable任务)抛出InterruptedException {
  最后CountDownLatch startGate=new CountDownLatch (1);
  最后CountDownLatch围板=new CountDownLatch (threadNums);
  for (int i=0;我& lt;threadNums;我+ +){
  线程t=新线程(){
  公共空间run () {
  尝试{//使线程在此等待,当开始门打开时,一起涌入门中
  startGate.await ();
  尝试{
  task.run ();
  最后}{//将结束门减1,减到0时,就可以开启结束门了
  endGate.countDown ();
  }
  }捕捉(InterruptedException ie) {
  ie.printStackTrace ();
  }
  }
  };
  t.start ();
  }
  长时间的开始时间=system . nanotime ();
  system . out。println(开始时间+ " " + Thread.currentThread() +”)所有线程准备好,并发去…”);//因开启门只需一个开关,所以立马就开启开始门
  startGate.countDown ();//等等结束门开启
  endGate.await ();
  长endTime=system . nanotime ();
  system . out。println (endTime + " " + Thread.currentThread() +”)所有线程完成。”);
  返回endTime——开始时间;
  } 
  

}   

执行结果
 CountDownLatch和CyclicBarrier模拟同时并发请求“> <br/> CyclicBarrier模拟</p>
  <blockquote>
  <p>//与闭锁结构一致<br/>公共类LatchTest {</p>
  </引用>
  <pre> <代码>公共静态void main (String [] args)抛出InterruptedException {
  
  Runnable taskTemp=new Runnable () {
  
  私人int iCounter;
  
  @Override
  公共空间run () {//发起请求</代码> </pre>
  <p>//HttpClientOp.doGet (“https://www.baidu.com/"); <br/> iCounter + +; <br/> System.out.println (system . nanotime () +“;[“;+ Thread.currentThread () . getname () +“] iCounter=?+ iCounter); <br/>} <br/>}; <h2 class=CountDownLatch和CyclicBarrier模拟同时并发请求