簡體   English   中英

如何避免同步和對象創建?

[英]How to avoid synchronization and object creation?

  1. 我使用JOGL用Java編寫了一個OpenGL應用程序。 我試圖完全避免在主應用程序階段創建對象,因為這可能會導致由GC引起的較小的周期性延遲。

  2. 我想用自己的方法包裝一些JOGL的方法。 想象一個方法void method(int[] result, int offset) ,該方法接收指向數組的指針和一個偏移量,並將一個整數值放入指定的索引處。 我想用簡單的int getResult()包裝它

  3. 因此,我需要在某個地方創建一個臨時數組,並且必須提前進行(根據1)。

  4. 但是,如果將其存儲在包含此wrapper方法的類的字段中,這將迫使我使wrapper方法成為synchronized 我知道大多數情況下單線程訪問的時間同步不會產生很大的開銷,但是我仍然想知道這是否有更好的解決方案。

筆記:

  • 同步不是答案,3.0000.000個空的同步塊,僅monitorenter-monitorexit需要17毫秒。 如果要保持60 fps,則只有16.(6)。

由於我沒有足夠的力量來投票,我發現欣賞Dave答案的唯一方法是編寫演示:

class Test {
    private static final int CYCLES = 1000000000;

    int[] global = new int[1];
    ThreadLocal<int[]> local = new ThreadLocal<int[]>();

                 void _fastButIncorrect() { global[0] = 1; }
    synchronized void _slowButCorrect()   { global[0] = 1; }

    void _amazing()   {
        int[] tmp = local.get();
        if( tmp == null ){
            tmp = new int[1];
            local.set(tmp);
        }
        tmp[0] = 1;
    }

    long fastButIncorrect() {
        long l = System.currentTimeMillis();
        for (int i = 0; i < CYCLES; i++) _fastButIncorrect();
        return System.currentTimeMillis() - l;
    }
    long slowButCorrect() {
        long l = System.currentTimeMillis();
        for (int i = 0; i < CYCLES; i++) _slowButCorrect();
        return System.currentTimeMillis() - l;
    }
    long amazing() {
        long l = System.currentTimeMillis();
        for (int i = 0; i < CYCLES; i++) _amazing();
        return System.currentTimeMillis() - l;
    }
    void test() {
        System.out.println(
                        "fastButIncorrect cold: " + fastButIncorrect() + "\n" +
                        "slowButCorrect   cold: " + slowButCorrect()   + "\n" +
                        "amazing          cold: " + amazing()          + "\n" +
                        "fastButIncorrect  hot: " + fastButIncorrect() + "\n" +
                        "slowButCorrect    hot: " + slowButCorrect()   + "\n" +
                        "amazing           hot: " + amazing()          + "\n"
        );
    }
    public static void main(String[] args) {
        new Test().test();
    }
}

在我的機器上,結果是:

fastButIncorrect cold: 40
slowButCorrect   cold: 8871
amazing          cold: 46
fastButIncorrect  hot: 38
slowButCorrect    hot: 9165
amazing           hot: 41

再次感謝,戴夫!

如果沒有太多線程,則可以使用ThreadLocal:

ThreadLocal<int[]> tmpArrayThreadLocal = new ThreadLocal<int[]>();

使用此代碼:

int[] tmpArray = tmpArrayThreadLocal.get();
if( tmpArray == null ){
   tmpArray = new int[100];
   tmpArrayThreadLocal.set(tmpArray);
}
method(tmpArray, 5)

您可以通過將ThreadLocal封裝在另一個類中來清理代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM