2017-03-12 48 views
0

我有两个线程,他们都读取相同的静态变量(一些大对象 - 一个500_000_000整数的数组)。Java静态变量和缓存

两个线程被固定到一个CPU(1和2)(CPU亲和力),所以尽量减少抖动。

你知道两个线程是否会因为两个线程在不同的cpu上运行而读取静态变量而相互减速吗?

import net.openhft.affinity.AffinityLock; 

public class BigObject { 
    public final int[] array = new int[500_000_000]; 
    public static final BigObject bo_static = new BigObject(); 

    public BigObject() { 
     for(int i = 0; i<array.length; i++){ 
      array[i]=i; 
     } 
    } 

    public static void main(String[] args) { 
     final Boolean useStatic = true; 
     Integer n = 2; 
     for(int i = 0; i<n; i++){ 
      final int k = i;  
      Runnable r = new Runnable() { 
       @Override 
       public void run() { 
        BigObject b; 
        if(useStatic){ 
         b = BigObject.bo_static; 
        } 
        else{ 
         b = new BigObject(); 
        } 
        try (AffinityLock al = AffinityLock.acquireLock()) { 
         while(true){ 
          long nt1 = System.nanoTime(); 
          double sum = 0; 
          for(int i : b.array){ 
           sum+=i; 
          } 
          long nt2 = System.nanoTime(); 
          double dt = (nt2-nt1)*1e-6; 
          System.out.println(k + ": sum " + sum + " " + dt); 
         } 
        } 
       } 
      }; 
      new Thread(r).start(); 
     } 
    } 
} 

感谢

+2

你能告诉我们一些代码吗? –

+0

只是增加了一些代码 – EKK

+0

数组总是分配在堆上 - 无论如何,如果您从静态或局部变量引用它们。读取一个CPU上的内存不应该影响另一个CPU上的内存(在典型的x86 CPU上) –

回答

0

在你的情况也不会有一个缓慢的做多线程下来 - 因为你正在做只读取无需您的CPU之间的无效任何共享的状态。

根据背景负载的不同,可能会有总线限制和内容,但是如果亲和性也是在操作系统级定义的 - 那么在易于预取的情况下将会有更多的CPU间和内核间的通信方式(因为您按顺序访问数据)比内存CPU通信。背景负载也会影响单线程情况下的性能 - 因此无需为此争论。

如果整个系统专用于您的程序 - 比现代CPU上的约20Gb/s的内存带宽更足够用于您的数据集。