并发压测java脚本你一定要会的3个类
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了并发压测java脚本你一定要会的3个类,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5781字,纯文字阅读大概需要9分钟。
内容图文
性能测试做到后面,一些特殊的场景利用常用的现成工具满足不了需求,所以你需要学习java写一些特定协议的压测脚本,那你不得不研究多线程或线程池,而此时你也一定会遇到java并发编程中的几个类,今天重点讲解这3个类,CountDownLanch、CyclicBarrier、Semaphore,希望大家以后看到的时候知道是干嘛用的。
接下来,我就最近学习的成果,下面和大家举例子讲解一下,帮助理解。
1CountDownLanch
场景
工作中往往会遇到需要异步处理的任务,此时我们就会利用多线程的方式去处理,即启动子线程去执行任务,而此时主线程阻塞,等待所有的子线程完成任务后,再去做一些汇总统计工作。
CountDownLanch 是一个倒数计数器, 给一个初始值(>=0), 然后每一次调用countDown就会减1, 这很符合等待多个子线程结束的场景: 一个线程结束的时候, countDown一次, 直到所有的线程都countDown了 , 那么所有子线程就都结束了。
先看看CountDownLanch提供的方法。
await: 会阻塞等待计数器减少到0位置. 带参数的await是多了等待时间。
countDown: 将当前的计数减1。
getCount(): 返回当前的计数。
显而易见, 我们只需要在子线程执行之前, 赋予初始化countDownLanch, 并赋予线程数量为初始值。
每个线程执行完毕的时候, 就countDown一下。主线程只需要调用await方法, 可以等待所有子线程执行结束。
例子
package?ht.test;
import?java.util.concurrent.CountDownLatch;
import?java.util.concurrent.CyclicBarrier;
public?class?CountDownLatchTest?{
????//?参数是2表示对象执行2次countDown方法才能释放锁
????static?CountDownLatch?c?=?new?CountDownLatch(2);
????public?static?void?main(String[]?args)?throws?InterruptedException?{
????????//?定义线程数
????????int?subThreadNum?=?5;
????????//?取得一个倒计时器,从5开始
????????CountDownLatch?countDownLatch?=?new?CountDownLatch(subThreadNum);
????????//?依次创建5个线程,并启动
????????for?(int?i?=?0;?i?<?subThreadNum;?i++)?{
????????????SubThread?runnablethread?=?new?SubThread(5000,?countDownLatch);
????????????new?Thread(runnablethread).start();
????????}
????????//?主线程工作,此处可以添加一些额外的工作
????????//?mainWork();
????????//?等待所有的子线程结束
????????countDownLatch.await();
????????System.out.println("all?all?all?Main?Thread?work?done!");
????}
????static?class?SubThread?implements?Runnable?{
????????private?CountDownLatch?countDownLatch;
????????private?long?workTime;
????????public?SubThread(long?workTime,?CountDownLatch?countDownLatch)?{
????????????this.workTime?=?workTime;
????????????this.countDownLatch?=?countDownLatch;
????????}
????????public?void?run()?{
????????????//?TODO?Auto-generated?method?stub
????????????try?{
????????????????System.out.println("线程Id:"?+?Thread.currentThread().getId()?+?"?Sub?thread?is?starting!");
????????????????Thread.sleep(workTime);
????????????????System.out.println("线程Id:"?+?Thread.currentThread().getId()?+?"?Sub?thread?is?stopping!");
????????????}?catch?(InterruptedException?e)?{
????????????????//?TODO?Auto-generated?catch?block
????????????????e.printStackTrace();
????????????}?finally?{
????????????????//?线程结束时,将计时器减一
????????????????countDownLatch.countDown();
????????????}
????????}
????}
}
2CyclicBarrier
场景
我们在做压测的时候,如要真正的并发,那么在创建线程成功后需要等待其他线程也创建好了,一起等着,同时发送请求,此时就用到了CyclicBarrier。
CyclicBarrier的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续运行。
例子
package?ht.test;
import?java.util.concurrent.CyclicBarrier;
public?class?CyclicBarrierTest?{
????//?初始化线程等待的个数,当调用await()函数的次数和这里的数值一致时候,接下去执行。
????static?CyclicBarrier?c?=?new?CyclicBarrier(2);
????public?static?void?main(String[]?args)?throws?Exception?{
????????new?Thread(new?Runnable()?{
????????????@Override
????????????public?void?run()?{
????????????????try?{
????????????????????//?子线程
????????????????????c.await();
????????????????}?catch?(Exception?e)?{
????????????????}
????????????????System.out.println(1);
????????????}
????????}).start();
????????try?{
????????????//?主线程,若此处注册掉,执行结果为2,并且子线程一直阻塞着
????????????c.await();
????????}?catch?(Exception?e)?{
????????}
????????System.out.println(2);
????}
}
3Semaphore
场景
有时候并发太大的时候,我们需要人工的控制,譬如一些数据库的连接数这样子的,资源毕竟有限的,不可能无限去创建连接,此时我们就需要利用Semaphore去控制。
Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源。可以控制系统的流量,拿到信号量的线程可以进入,否则就等待。通过acquire()和release()获取和释放访问许可。
例子
package?ht.test;
import?java.util.concurrent.ExecutorService;
import?java.util.concurrent.Executors;
import?java.util.concurrent.Semaphore;
public?class?TestSemaphore?{
????public?static?void?main(String[]?args)?{
????????//?线程池
????????ExecutorService?exec?=?Executors.newCachedThreadPool();
????????//?只能5个线程同时访问
????????final?Semaphore?semp?=?new?Semaphore(5);
????????//?模拟20个客户端访问
????????for?(int?index?=?0;?index?<?20;?index++)?{
????????????final?int?NO?=?index;
????????????Runnable?run?=?new?Runnable()?{
????????????????@Override
????????????????public?void?run()?{
????????????????????try?{
????????????????????????//?获取许可
????????????????????????semp.acquire();
????????????????????????System.out.println("Accessing:?"?+?NO);
????????????????????????//?模拟实际业务逻辑
????????????????????????Thread.sleep((long)?10000);
????????????????????????//?访问完后,释放
????????????????????????semp.release();
????????????????????}?catch?(InterruptedException?e)?{
????????????????????}
????????????????}
????????????};
????????????exec.execute(run);
????????}
????????try?{
????????????Thread.sleep(100);
????????}?catch?(InterruptedException?e)?{
????????????e.printStackTrace();
????????}
????????//?System.out.println(semp.getQueueLength());
????????//?退出线程池
????????exec.shutdown();
????}
}
不知道,你有没有理解,在此也只是抛砖引玉一下,大家在实践中可以继续学习研究。
更多其他测试内容可以参考链接文末更多测试好文章
内容总结
以上是互联网集市为您收集整理的并发压测java脚本你一定要会的3个类全部内容,希望文章能够帮你解决并发压测java脚本你一定要会的3个类所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。