Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中AtomicInteger与synchronized int变量:性能差异_Java_Atomic_Synchronized_Java.util.concurrent - Fatal编程技术网

Java中AtomicInteger与synchronized int变量:性能差异

Java中AtomicInteger与synchronized int变量:性能差异,java,atomic,synchronized,java.util.concurrent,Java,Atomic,Synchronized,Java.util.concurrent,经过下面的问题 , 我编写了一个简单的程序来比较AtomicInteger和synchronized块(在其中递增int)的性能差异。每次我运行这个程序,它给我的比率>100。 我的笔记本电脑有Intel Corei3和以下第4行 System.out.println(Runtime.getRuntime().availableProcessors()) 当我使用 THREAD_COUNT = 1; 这个比率是最低的。它在100左右变化。为了 THREAD_COUNT

经过下面的问题 ,
我编写了一个简单的程序来比较AtomicInteger和synchronized块(在其中递增int)的性能差异。每次我运行这个程序,它给我的比率>100。 我的笔记本电脑有Intel Corei3和以下第4行

    System.out.println(Runtime.getRuntime().availableProcessors())
当我使用

    THREAD_COUNT = 1;
这个比率是最低的。它在100左右变化。为了

    THREAD_COUNT = 10;  
比率约为800

问题1:您能告诉我这是测试AtomicInteger与synchronized increment()方法性能差异的正确方法吗

问题2:如果我增加
线程数
,比率会增加,为什么?我认为这是因为更多的线程在synchronized语句中被阻塞,需要更多的CPU任务。请评论

package concurrent.atomic;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class Performance {

    private static final AtomicInteger atomicInt = new AtomicInteger(0);
    private static volatile int counter = 0;
    private static final Object LOCK = new Object();
    private static final int THREAD_COUNT = 10;

    public static void main(String[] args) {

        System.out.println(Runtime.getRuntime().availableProcessors()); 

        Runnable atomic = new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    int value = atomicInt.incrementAndGet();
                    //if (value % 1000 == 0)
                        //System.out.println("atomic value : "+value);
                }   
            }
        };
        //System.out.println("1");
        Runnable intCounter = new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    synchronized (LOCK) {
                        int value = ++counter;
                        //if (value % 1000 == 0)
                            //System.out.println("sync value "+value);
                    }
                }   
            }
        };

        final ExecutorService atomicExecutor = Executors.newCachedThreadPool();
        final ExecutorService primitiveExecutor = Executors.newCachedThreadPool();
        for (int i = 0; i < THREAD_COUNT ; ++i) {
            atomicExecutor.submit(atomic);
            primitiveExecutor.submit(intCounter);
        }

        while (true) {
            float ratio = (((float) (atomicInt.get() * 1.0) ) / counter) * 100;
            System.out.println("ratio : " + ratio);
        }
    }
}
package concurrent.atomic;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
导入java.util.concurrent.AtomicInteger;
公开课表演{
私有静态最终AtomicInteger atomicInt=新的AtomicInteger(0);
专用静态易失性int计数器=0;
私有静态最终对象锁=新对象();
私有静态最终整数线程计数=10;
公共静态void main(字符串[]args){
System.out.println(Runtime.getRuntime().availableProcessors());
Runnable-atomic=新的Runnable(){
@凌驾
公开募捐{
而(!Thread.currentThread().isInterrupted()){
int value=atomicInt.incrementAndGet();
//如果(值%1000==0)
//System.out.println(“原子值:“+value”);
}   
}
};
//系统输出打印项次(“1”);
Runnable intCounter=new Runnable(){
@凌驾
公开募捐{
而(!Thread.currentThread().isInterrupted()){
已同步(锁定){
int值=++计数器;
//如果(值%1000==0)
//System.out.println(“同步值”+值);
}
}   
}
};
final ExecutorService atomicExecutor=Executors.newCachedThreadPool();
final ExecutorService primitiveExecutor=Executors.newCachedThreadPool();
对于(int i=0;i
问题1:你能告诉我这是测试AtomicInteger与synchronized increment()方法性能差异的正确方法吗

测试代码存在一些微妙的问题:

  • 如果在
    锁上进行同步
    ,则
    计数器
    不应为
    易失性
    。否则,
    synchronized
    代码将支付锁和
    volatile
    的费用
  • 如果
    计数器
    不是
    易失性
    ,则在读取
    计数器
    的值时,需要在
    锁定
    上进行同步
  • 你不应该在主线程中旋转。这将极大地影响您的性能测试。放一个
    线程。睡眠(100)循环时,在
    中执行code>
  • 原来
    Thread.currentThread().isInterrupted()
    在我的Mac上非常昂贵。不知道为什么。当(true)
    更改数字时,将其切换为
有了这个,你就有了一个更好的两个测试,尽管这种孤立的测试除了告诉我们你正在测试的东西之外,并没有告诉我们任何东西。连续执行一百万次中断与将20次中断混合到实际代码中非常不同

问题2:如果我增加线程数,比率会增加,为什么?我认为这是因为更多的线程在synchronized语句中被阻塞,需要更多的CPU任务。请评论

package concurrent.atomic;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

public class Performance {

    private static final AtomicInteger atomicInt = new AtomicInteger(0);
    private static volatile int counter = 0;
    private static final Object LOCK = new Object();
    private static final int THREAD_COUNT = 10;

    public static void main(String[] args) {

        System.out.println(Runtime.getRuntime().availableProcessors()); 

        Runnable atomic = new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    int value = atomicInt.incrementAndGet();
                    //if (value % 1000 == 0)
                        //System.out.println("atomic value : "+value);
                }   
            }
        };
        //System.out.println("1");
        Runnable intCounter = new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    synchronized (LOCK) {
                        int value = ++counter;
                        //if (value % 1000 == 0)
                            //System.out.println("sync value "+value);
                    }
                }   
            }
        };

        final ExecutorService atomicExecutor = Executors.newCachedThreadPool();
        final ExecutorService primitiveExecutor = Executors.newCachedThreadPool();
        for (int i = 0; i < THREAD_COUNT ; ++i) {
            atomicExecutor.submit(atomic);
            primitiveExecutor.submit(intCounter);
        }

        while (true) {
            float ratio = (((float) (atomicInt.get() * 1.0) ) / counter) * 100;
            System.out.println("ratio : " + ratio);
        }
    }
}
AtomicInteger.incrementAndGet()
通过旋转工作,直到测试和设置成功。这与锁获取、增量和释放非常不同。在不知道操作系统线程处理细节的情况下,很难解释这里发生了什么,我不确定这在所有情况下都是正确的


在我的测试中,随着线程的数量越来越多地超过处理器的数量,这个比率往往会有相当大的波动。随着更多线程的添加,
synchronize
处理明显受到并发性增加的影响,尽管我不确定还能从中得出什么结论。

做到了这一点。我在谷歌上找到了这个。试试这个。你这里有一个bug,你需要将
计数器
声明为
volatile
。否则,不能保证主线程读取最新的值。是。。我需要更改我的代码。你的分析有道理。您可以不时将计数器重置为0,以避免溢出,更重要的是在JIT前后进行计算。