Java中多线程的性能比较

Java中有多种用于多线程的技术。 可以通过同步关键字,锁或原子变量来并行化Java中的一段代码。 这篇文章将比较使用synced关键字ReentrantLock,getAndIncrement()以及执行get()和compareAndSet()调用的连续试验的性能。 创建了不同类型的Matrix类以进行性能测试,其中还包括一个普通类。 为了进行比较,在具有Intel Core I7(具有8个核心,其中4个是真实的),Ubuntu 14.04 LTS和Java的计算机上,对于不同大小的矩阵,具有不同类型的同步,线程数和池大小,所有单元都增加了100倍。 1.7.0_60。

这是性能测试的简单矩阵类:

/**
* Plain matrix without synchronization.
*/
public class Matrix {
private int rows;
private int cols;
private int[][] array;
/**
* Matrix constructor.
*
* @param rows number of rows
* @param cols number of columns
*/
public Matrix(int rows, int cols) {
this.rows = rows;
this.cols = cols;
array = new int[rows][rows];
}
/**
* Increments all matrix cells.
*/
public void increment() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
array[i][j]++;
}
}
}
/**
* Returns a string representation of the object which shows row sums of each row.
*
* @return a string representation of the object.
*/
@Override
public String toString() {
StringBuffer s = new StringBuffer();
int rowSum;
for (int i = 0; i < rows; i++) {
rowSum = 0;
for (int j = 0; j < cols; j++) {
rowSum += array[i][j];
}
s.append(rowSum);
s.append(" ");
}
return s.toString();
}
}

对于其他矩阵,由于每种矩阵类型的剩余部分相同,因此列出了它们的增量方法。 同步矩阵:

public void increment() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
synchronized (this) {
array[i][j]++;
}
}
}
}

锁矩阵:

public void increment() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
lock.lock();
try {
array[i][j]++;
} finally {
lock.unlock();
}
}
}
}

原子getAndIncrement矩阵:

public void increment() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
array[i][j].getAndIncrement();
}
}
}

连续尝试get()和compareAndSet()矩阵:

public void increment() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
for (; ; ) {
int current = array[i][j].get();
int next = current + 1;
if (array[i][j].compareAndSet(current, next)) {
break;
}
}
}
}
}

还为每个矩阵创建了工人类别。 这是普通工人阶级:

/**
* Worker for plain matrix without synchronization.
*
* @author Furkan KAMACI
* @see Matrix
*/
public class PlainMatrixWorker extends Matrix implements Runnable {
private AtomicInteger incrementCount = new AtomicInteger(WorkerDefaults.INCREMENT_COUNT);
/**
* Worker constructor.
*
* @param rows number of rows
* @param cols number of columns
*/
public PlainMatrixWorker(int rows, int cols) {
super(rows, cols);
}
/**
* Increments matrix up to a maximum number.
*
* @see WorkerDefaults
*/
@Override
public void run() {
while (incrementCount.getAndDecrement() > 0) {
increment();
}
}
}

为了进行正确的比较,默认情况下,所有测试都会被重复20次。 计算每个结果的平均和标准误差。 由于测试集有很多维度(矩阵类型,矩阵大小,池大小,线程数和经过时间),因此某些功能在图表中汇总显示。 结果如下:对于池大小2和线程数2:

2-2

对于池大小4和线程数4:

4-4

对于池大小6和线程数6:

6-6

对于池大小8和线程数8:

8-8

对于池大小10和线程数10:

10-10

对于池大小12和线程数12:

12-12

结论

可以很容易地看到普通版本运行最快。 但是,它不会产生预期的正确结果。 同步块的性能更差(使用“ this ”完成同步时)。 锁比同步块稍好。 但是,原子变量在所有变量中都明显更好。 当原子getAndIncrement以及对get()和compareAndSet()调用的连续试验进行比较时,表明它们的性能相同。 检查Java源代码时,很容易理解其背后的原因:

/**
* Atomically increments by one the current value.
*
* @return the previous value
*/
public final int getAndIncrement() {
for (;;) {
int current = get();
int next = current + 1;
if (compareAndSet(current, next))
return current;
}
}

可以看出,在Java(1.7版)源代码中,通过对get()和compareAndSet()进行连续试验来实现getAndIncrement。 另一方面,当检查其他结果时,可以看到池大小的影响。 当使用的池大小小于实际线程数时,将发生性能问题。 因此,Java中多线程的性能比较表明,当确定要同步一段代码并且出现性能问题时,如果像测试中那样使用此类线程,则应尝试使用Atomic变量。 其他选择应该是锁或同步块。 同样,这并不意味着由于JIT编译器的影响并且多次运行一段代码,同步块总是比锁更好。

  • 可以从此处下载用于Java多线程性能比较的源代码: https : //github.com/kamaci/performance

翻译自: https://www.javacodegeeks.com/2015/05/performance-comparison-of-multithreading-in-java.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/358898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【leetcode】Remove Linked List Elements(easy)

Remove all elements from a linked list of integers that have value val. ExampleGiven: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val 6Return: 1 --> 2 --> 3 --> 4 --> 5 思路&#xff1a;简单题。 //Definition for singly-linked list.…

微软ms10_018漏洞的利用

微软ms10_018漏洞的利用 0x00 前言0x01 study1. 漏洞利用环境1.1 目标机环境1.2 攻击机环境1.3 拓扑结构 2. ping测试3. exploit3.1 启动Metasploit3.2 查找和MS10-018相关的模块3.3 加载模块3.4 设置PAYLOAD3.5 显示需要配置的选项3.6 设置Web服务器的地址&#xff0c;应为Ba…

【深度】机器学习进化史:从线性模型到神经网络

【深度】机器学习进化史&#xff1a;从线性模型到神经网络 Reza Zadeh是斯坦福大学工程计算和数学研究所顾问教授&#xff0c;也是Databricks公司技术顾问&#xff0c;他主要专注于机器学习理论和应用&#xff0c;分布式计算&#xff0c;以及离散应用数学。近日&#xff0c;他接…

python能不能用c打开文件_C/C++/Python等 使用二进制模式打开文件与不使用二进制模式的区别...

C语言中文本文件与二进制文件的区别 一、文本文件与二进制文件的定义 大家都知道计算机的存储在物理上是二进制的&#xff0c;所以文本文件与二进制文件的区别并不是物理上的&#xff0c;而是逻辑上的。这两者只是在编码层次上有差异。 简单来说&#xff0c;文本文件是基于字符…

微软MS10-046漏洞的利用

微软MS10-046漏洞的利用 0x00 前言0x01 环境1. 目标机环境2. 攻击机环境3. 拓扑结构 0x02 过程1. 相互ping通2. 启动Metasploit3. 查找和MS10-046相关的模块4. 加载模块5. 设置所使用的payload6. 设置文件共享服务器的地址&#xff0c;应为BackTrack虚拟机的地址7. 设置目标主…

修改mysql 外删除用户_mysql添加用户、删除用户、授权、修改密码等

mysql添加用户、删除用户、授权、修改密码等1.新建用户。 //登录MYSQL >mysql -u root -p >密码 //创建用户 mysql> mysql> insert into mysql.user(Host,User,Password,ssl_cipher,x509_issuer,x509_sub ject) values("localhost","pppadmin"…

Loadrunner日志设置与查看

Loadrunner日志设置与查看 1.打开EXtended LogLog告诉了我们一切,默认的Log是standard Log,这时远远不够的.我们要extended log,打开路径为runtime settings-->log-->extended log.把parameter substitution和data returned byserver和advanced trace大家根据需要勾选吧.…

使用七牛云对网站进行加速基本配置

看了很多给网站加速的教程,大同小异,觉得还是使用免费的七牛云进行CDN加速,去年使用这个平台给APP加速,效果还不错。 1.打开七牛云存储注册链接:七牛云 注册帐号并且完成系统要求的实名认证要求。一般不需要充钱,冲着免费去的,既可以获得免费的10G流量,一般的小型网站…

java与java ee_Java EE6装饰器:在注入时装饰类

java与java ee软件中常见的设计模式是装饰器模式 。 我们上一堂课&#xff0c;然后在它周围包装另一堂课。 这样&#xff0c;当我们调用类时&#xff0c;我们总是在到达内部类之前通过周围的类。 Java EE 6允许我们通过CDI创建装饰器&#xff0c;作为其AOP功能的一部分。 如果我…

kail利用msf工具对ms10-087漏洞入侵渗透WinXP

1.实验环境: Kali2020:10.20.29.129 Windows 2003:10.20.29.137 两台虚拟机能够相互ping通 2.实验步骤 1&#xff0c; 启动Metasploit 2&#xff0c;查找和MS10-087相关的模块search ms10_087 3&#xff0c;使用exploit/windows/fileformat/ms10_087_rtf_pfragments_bof模…

java gif_使用Java来处理GIF图片

一个2个类&#xff0c;一个是读图片的类GifDecoder&#xff0c;一个是写图片的类AnimatedGifEncoder使用还是挺方便的&#xff0c;下面举个栗子public static void main(String[] args) throws IOException {GifDecoder decoder new GifDecoder();int status decoder.read(&q…

C++ operator 知识点

[转]C隐式类型转换 operator T http://m.blog.csdn.net/blog/micx0124/12389973# 对于operator关健字用于运算符重载这我们都知道&#xff0c;其实operator还有另外一种作用&#xff1a;强制类型转换。上一周为了对应项目中一个问题&#xff0c;同事帮助写了一个类&#xff0c;…

2020年前端招聘技术概览(包含常见的打包工具,框架及前端技术简介)

学习当下前端技术最好的方法就是从求职网站上找出前端的招聘要求,因为前端技术每年变化都很快,每个阶段都会不一样,这里简单从网站招聘要求罗列,仅供参考。更有针对性的是针对每个公司的招聘要求写简历,学习相关技术(除非那个公司特别好) 1.熟悉html,javaScript,css,aja…

java.util.concurrent包

本文是我们学院课程中名为Java Concurrency Essentials的一部分 。 在本课程中&#xff0c;您将深入探讨并发的魔力。 将向您介绍并发和并发代码的基础知识&#xff0c;并学习诸如原子性&#xff0c;同步和线程安全之类的概念。 在这里查看 &#xff01; 目录 1.简介 2. jav…

DVWA通关教程(下)

XSS&#xff08;DOM&#xff09; XSS(DOM)是一种基于DOM树的一种代码注入攻击方式&#xff0c;可以是反射型的&#xff0c;也可以是存储型的&#xff0c;所以它一直被划分第三种XSS 与前两种XSS相比&#xff0c;它最大的特点就是不与后台服务器交互&#xff0c;只是通过浏览器…

Python模拟ICMP包

主要使用Scapy来完成 基础环境 VM1&#xff08;192.168.1.226&#xff09; | | VM2&#xff08;192.168.1.125&#xff09; vm1封装icmp包发给vm2 vm1脚本&#xff1a; #! /usr/bin/env pythonfrom scapy.all import *target "192.168.1.125" ip IP() icmp ICMP()…

SSH暴力破解实战

一.hydra【海德拉】 海德拉&#xff08;Hydra&#xff09;&#xff1a;希腊神话中的九头蛇&#xff0c;是西方的神话生物&#xff0c;在古希腊神话中出现最为频繁。传说它拥有九颗头&#xff0c;其中一颗头要是被斩断&#xff0c;立刻又会生出两颗头来。 Hydra是世界顶级密码暴…

前端工程师必备谷歌浏览器F12下的调试知识点

chrome浏览器版本(所有的操作都是基于我电脑上目前这个版本。) 进入开发者工具的方式:F12 (所有浏览器都可以用F12进入开发者工具),ChromeDev(开发者工具简称)按照类别可以分为下面几种 审查元素 ctrl+shift+c 在页面上选择一个HTML元素并审查它 切换浏览设备 ctrl+…

java createjpeg4_在linux下用java的JPEGCodec.createJPEGEncoder(bos)生成jpg图片问题

在rh8 linux 下用java的JPEGCodec.createJPEGEncoder(bos)生成jpg图片&#xff0c;XServer已启动。出现如下问题错误提示如下java.lang.InternalError: Cant connect to X11 window server using :0.0 as the value of the DISPLAY variable…

ASP.Net string 类的扩展方法 [转]

string 类的扩展方法列表(基本相同于 IEnumerable<T> 接口的成员列表): Aggregate<> //累加 All<> //是否都满足条件 Any<> //是否有一个满足条件 AsEnumerable<> // AsParallel<> …