简单测试Java线程安全中阻塞同步与非阻塞同步性能
2024-10-19 19:44:49
摘抄自周志明老师的《深入理解Java虚拟机:JVM高级特性与最佳实践》13.2.2 线程安全的实现方法
1.名词解释
同步是指锁哥线程并发访问共享数据时,保证共享数据同一时刻只被一个线程访问
互斥同步(阻塞同步)是一种悲观的并发策略,总是认为只要不去做正确的同步措施(加锁),那就肯定会出现问题。
阻塞同步最主要的问题是进行线程阻塞和唤醒所带来的性能问题,因为在JDK 1.2之后,Java的线程模型被替换为基于操作系统原生线程模型来实现,如要阻塞唤醒一个线程,都需要操作系统来帮忙完成,这就需要用户态转换到内核态,会耗费很多时间。
非阻塞同步:随着硬件指令集的发展,我们有了另一种选择:基于冲突检测的乐观并发策略,这种操作不需要挂起线程,会节省很多时间,比如CAS(compare and swap)指令。
2.开始测试
第一种加锁方式:
static int a=0;
public static void lock() {
Thread[] threads=new Thread[50];
for(int i=0;i<threads.length;i++){
threads[i]=new Thread(new Runnable() { @Override
public void run() {
for(int i=0;i<100000;i++){
synchronized(Main.class){
a++;
}
}
}
});
threads[i].start();
}
while(Thread.activeCount() > 1){
Thread.yield();
}
System.out.println(a);
}
第二种CAS方式:
static AtomicInteger integer=new AtomicInteger(0);
public static void cas() {
Thread[] threads=new Thread[50];
for(int i=0;i<threads.length;i++){
threads[i]=new Thread(new Runnable() { @Override
public void run() {
for(int i=0;i<100000;i++){
integer.incrementAndGet();
}
}
});
threads[i].start();
}
while(Thread.activeCount() > 1){
Thread.yield();
}
System.out.println(integer.get());
}
3结论:运行两个方法,同样是50个线程,100000个自增,输出时间差,可以看到性能之间的差异。
lock方法平均在1270ms
cas方法平均在175ms
可以看到阻塞同步与非阻塞同步之间巨大的差异,也可以看出Java线程用户态内核态切换损耗的处理器时间很大。
最新文章
- Hawk 5.1 数据导入和导出
- 在运行Hibernate Hello World程序的时候,抛如下错误: view plain Exception in thread ";main"; org.hibernate.exception.LockAcquisitionException 解决方法
- an interview question(2)
- [Java Basics3] XML, Unit testing
- ViewPager+Fragment实现页面的切换
- ACM: 限时训练题解-Epic Professor-水题
- HTTP请求报文和HTTP响应报文(转)
- (转)Java并发编程:volatile关键字解析
- Java——多线程
- Windows环境自动获取AWR报告
- C++中cin、cin.get()、cin.getline()、getline()、gets()等函数的用法
- html不同文档类型支持的元素标签
- Linux系列教程(二十一)——Linux的bash基本功能
- 实战DeviceIoControl 之一:通过API访问设备驱动程序
- OKR能解决996吗?德鲁克怎么看?
- PID控制最通俗的解释与PID参数的整定方法
- input 特殊字符限制
- python,栈的小例子
- C语言函数调用栈(三)
- Hdu1427 速算24点 2017-01-18 17:26 46人阅读 评论(0) 收藏