count++线程安全与 synchronized对性能影响的测试
一个计时器,同时开启100个线程,每个线程休眠1ms钟后,将全局静态变量count加1,这100个线程创建完之后,休眠500ms,计算总耗时,程序如下:
public class Counter {
public volatile static int count = 0;
public static void inc() {
// 这里延迟1毫秒,使得结果明显
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
count++;
}
public static void main(String[] args) {
long time1 = System.currentTimeMillis();
System.out.println();
for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
Counter.inc();
}
}).start();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 这里每次运行的值都有可能不同,可能为100
System.out.println("Counter.count=" + Counter.count);
long time2 = System.currentTimeMillis();
System.out.println("耗时:"+(time2-time1));
}
}
运行结果:
Counter.count=96
耗时:506
Counter.count不等于100是因为count++线程不安全。
加上同步代码块:
public class Counter {
public volatile static int count = 0;
static Object obj = new Object();
public static void inc() {
// 这里延迟1毫秒,使得结果明显
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
synchronized (obj) {
count++;
}
}
public static void main(String[] args) {
long time1 = System.currentTimeMillis();
System.out.println();
for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
Counter.inc();
}
}).start();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 这里每次运行的值都有可能不同,可能为1000
System.out.println("Counter.count=" + Counter.count);
long time2 = System.currentTimeMillis();
System.out.println("耗时:"+(time2-time1));
}
}
运行结果:
Counter.count=100
耗时:507
那么synchronized对运行的速度有多大的影响,于是我分别100,1000,10000,100000与500000次,将未同步、synchronized (obj)与synchronized (Counter.class)结果对比,结果如下:
| 线程数量 | 未同步<测试更多的数据> | synchronized (obj) | synchronized (Counter.class) |
| 100 | Counter.count=97 耗时:508 <98-506><98-507><97-507><100-508> |
Counter.count=100 耗时:507 <100-507><100-507><100-508><100-508> |
Counter.count=100 耗时:506 <100-508><100-508><100-506><100-509> |
| 1000 | Counter.count=997 耗时:572 <993-562><994-562><995-561><990-561> |
Counter.count=1000 耗时:562 <1000-572><1000-560><1000-559><1000-560> |
Counter.count=1000 耗时:570 <1000-585><1000-560><1000-562><1000-561> |
| 10000 | Counter.count=9947 耗时:1067 <9951-1077><9962-1079><9936-1066><9953-1081> |
Counter.count=10000 耗时:1074 <10000-1075><10000-1068><10000-1079><10000-1074> |
Counter.count=10000 耗时:1072 <10000-1089><10000-1076><10000-1108><10000-1076> |
| 100000 | Counter.count=99399 耗时:6098 <99347-6111><99374-6099><99416-6196><99459-6137> |
Counter.count=100000 耗时:6103 <100000-6101><100000-6104><100000-6155><100000-6107> |
Counter.count=100000 耗时:6150 <100000-6287><100000-6182><100000-6159><100000-6104> |
| 500000 | Counter.count=497242 耗时:28892 <497394-30674><497274-29864><497129-29470><497216-29529> |
Counter.count=500000 耗时:31232 <500000-29297><500000-29053><500000-29166><500000-29006> |
Counter.count=500000 耗时:29251 <500000-29743><500000-29334><500000-29600><500000-29848> |
将上面耗时时间求平均值,得到:
| 线程数量 | 未同步平均用时 | synchronized (obj)平均用时 | synchronized (Counter.class)平均用时 |
| 100 | 507.2 | 507.4 | 507.4 |
| 1000 | 563.6 | 562.6 | 567.6 |
| 10000 | 1074 | 1074 | 1084.2 |
| 100000 | 6128.2 | 6114 | 6176.4 |
| 500000 | 29685.8 | 29550.8 | 29555.2 |
于是,得出结论:
1、synchronized可以解决多线程造成的count++不准确的问题。
2、随着线程数量的增加,加过synchronized后的代码,并不会对速度产生很明显的影响。
3、从1万与10万的结果来看,经过synchronized(obj)处理后的程序,要比synchronized(Counter.class)处理后的程序大约要快10ms。而100、1000与50万,synchronized(obj)与synchronized(Counter.class)执行速度几乎相等。从总体来看,随着线程数量的增加,synchronized(Counter.class)执行的效率并没有明显的低于synchronized(obj)。
count++线程安全与 synchronized对性能影响的测试的更多相关文章
- 关于nagios监控远程服务器对服务器性能影响的测试
1. Nagios监视远程服务器时,是通过在控制端执行以下命令进行数据收集的: /usr/local/nagios/libexec/check_http -I 192.168.16.11 /us ...
- 线程变量(ThreadLocal)的使用和测试
ThreadLocal可以定义线程范围的变量,也可以称之为线程局部变量.与一般的变量的区别在于,生命周期是在线程范围内的. 也就是说某个类的某个对象(为清晰描述,以下称A对象)里面有个ThreadLo ...
- 线程池 队列 synchronized
线程池 BlockingQueue synchronized volatile 本章从线程池到阻塞队列BlockingQueue.从BlockingQueue到synchronized 和 volat ...
- 从线程池到synchronized关键字详解
线程池 BlockingQueue synchronized volatile 前段时间看了一篇关于"一名3年工作经验的程序员应该具备的技能"文章,倍受打击.很多熟悉而又陌生的知识 ...
- Synchronized锁性能优化偏向锁轻量级锁升级 多线程中篇(五)
不止一次的提到过,synchronized是Java内置的机制,是JVM层面的,而Lock则是接口,是JDK层面的 尽管最初synchronized的性能效率比较差,但是随着版本的升级,synchro ...
- .Net Discovery系列之十二-深入理解平台机制与性能影响(下)
上一篇文章中Aicken为大家介绍了.Net平台的垃圾回收机制.即时编译机制与其对性能的影响,这一篇中将继续为大家介绍.Net平台的异常捕获机制与字符串驻留机制. 三.关于异常捕获机制 虽然我们已经很 ...
- 线程的同步控制synchronized和lock的对比和区别
转载. https://blog.csdn.net/wu1226419614/article/details/73740899 我们在面试的时候,时常被问到如何保证线程同步已经对共享资源的多线程编程 ...
- 线程安全与synchronized
线程安全性与synchronized 线程安全:多线程访问某个类时,这个类始终都能表现出正确的行为,这个类就是线程安全的. 简单的说,就是多线程执行的结果与单线程执行的结果始终一致,不会因为多线程的执 ...
- ToList<>()所带来的性能影响
ToList<>()所带来的性能影响 前几天优化师弟写的代码,有一个地方给我留下很深刻的印象,就是我发现他总是将PLINQ的结果ToList<>(),然后再返回给主程序,对于 ...
随机推荐
- Access restriction: The type Resource is not accessible due to restriction on required library
方法一: 全局属性Project>preferences>java>Compiler>Errors/Warnings>把右侧的[Deprecated and restri ...
- cookie js案例
//存cokie function setcookie(keys,value,time){ document.cookie=keys+"="+decodeURIComponent( ...
- js轮播插件
// Tween算法 var Tween = { // t:当前步数 // b:初始位置 // c:总距离 // d:总步数 // Linear:匀速 Linear: function(t,b,c,d ...
- Ubuntu 11.10 H3C iNode 客户端安装
下载客户端,放到桌面 双击打开,点击解压缩 Ctrl+Alt+T打开终端,依次输入以下代码并回车 代码: cd 桌面sudo cp iNodeClient /usr -Rcd /usr/iNodeCl ...
- jquery二维码生成插件_二维码生成器
jquery二维码生成插件_二维码生成器 下载地址:jquery生成二维码.rar
- VS2013下.Net Framework4配置FineUI4.14
配置步骤: 工具箱:空白处右键--选项卡--浏览,选择FineUI.dll配置web.config,管道模式设置为:传统 配置web.config 在form表单下添加: <f:PageMana ...
- ioncube 加密软件 linux 使用方法
https://www.ioncube.com/sa_encoder.php?page=pricing 购买成功后 解压文件包 装了一个linux 版的加密软件 目录:/webdata/soft/io ...
- python的XML处理模块ElementTree
ElementTree是python的XML处理模块,它提供了一个轻量级的对象模型.它在Python2.5以后成为Python标准库的一部分,但是Python2.4之前需要单独安装.在使用Elemen ...
- ajaxGet 获取封装
callback 表示下一个功能(回调函数) function ajaxGet(url,callback,data){ 如果路径上有参数 就在url后面拼接参数 否则只请求url ...
- [python爬虫] 爬取图片无法打开或已损坏的简单探讨
本文主要针对python使用urlretrieve或urlopen下载百度.搜狗.googto(谷歌镜像)等图片时,出现"无法打开图片或已损坏"的问题,作者对它进行简单的探讨.同时 ...