java中System.arraycopy是线程安全的吗?
巴扎黑
巴扎黑 2017-04-18 10:23:09
0
3
851

请问一下 在java中System.arraycopy是不是线程安全的

巴扎黑
巴扎黑

répondre à tous(3)
小葫芦

System.arraycopy est une méthode native :

public static native void arraycopy(Object src,  int  srcPos,
                                    Object dest, int destPos,
                                    int length);

Il n'y a pas de lien nécessaire entre la méthode native et la sécurité des threads, et j'ai vu que la documentation de System.arraycopy ne mentionnait pas qu'elle était thread-safe, nous pouvons donc savoir que c'est 线程不安全的.

Mais afin de vérifier si System.arraycopy est vraiment thread-unsafe, j'ai écrit un petit exemple :

public class ArrayCopyThreadSafe {
    private static int[] arrayOriginal = new int[1024 * 1024 * 10];
    private static int[] arraySrc = new int[1024 * 1024 * 10];
    private static int[] arrayDist = new int[1024 * 1024 * 10];
    private static ReentrantLock lock = new ReentrantLock();

    private static void modify() {
        for (int i = 0; i < arraySrc.length; i++) {
            arraySrc[i] = i + 1;
        }
    }

    private static void copy() {
        System.arraycopy(arraySrc, 0, arrayDist, 0, arraySrc.length);
    }

    private static void init() {
        for (int i = 0; i < arraySrc.length; i++) {
            arrayOriginal[i] = i;
            arraySrc[i] = i;
            arrayDist[i] = 0;
        }
    }

    private static void doThreadSafeCheck() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("run count: " + (i + 1));
            init();
            Condition condition = lock.newCondition();

            new Thread(new Runnable() {
                @Override
                public void run() {
                    lock.lock();
                    condition.signalAll();
                    lock.unlock();
                    copy();
                }
            }).start();


            lock.lock();
            // 这里使用 Condition 来保证拷贝线程先已经运行了.
            condition.await();
            lock.unlock();

            Thread.sleep(2); // 休眠2毫秒, 确保拷贝操作已经执行了, 才执行修改操作.
            modify();

            if (!Arrays.equals(arrayOriginal, arrayDist)) {
                throw new RuntimeException("System.arraycopy is not thread safe");
            }
        }
    }

    public static void main(String[] args) throws Exception {
        doThreadSafeCheck();
    }
}

Le fonctionnement spécifique de cet exemple est :

  1. arrayOriginal et arraySrc sont identiques une fois initialisés, tandis que arrayDist est entièrement composé de zéros.

  2. Démarrez un fil de discussion pour exécuter la méthode copy() pour copier arraySrc dans arrayDist.

  3. exécute l'opération modify() dans le thread principal et modifie le contenu de arraySrc Afin de m'assurer que l'opération copy() précède l'opération modify(), j'utilise Condition et je la retarde de deux millisecondes. assurez-vous que la copie est exécutée (c'est-à-dire System.arraycopy) avant l'opération de modification.

  4. Selon le troisième point, si System.arraycopy est thread-safe, alors effectuer d'abord l'opération de copie, puis effectuer l'opération de modification n'affectera pas le résultat de la copie, donc arrayOriginal doit être égal à arrayDist et if ; System.arraycopy est 线程不安全的, alors arrayOriginal n'est pas égal à arrayDist.


Sur la base du raisonnement ci-dessus, exécutez le programme et obtenez le résultat suivant :

run count: 1
run count: 2
Exception in thread "main" java.lang.RuntimeException: System.arraycopy is not thread safe
    at com.test.ArrayCopyThreadSafe.doThreadSafeCheck(ArrayCopyThreadSafe.java:62)
    at com.test.ArrayCopyThreadSafe.main(ArrayCopyThreadSafe.java:68)

Comme vous pouvez le constater, cela a bien fonctionné les deux premières fois, mais pas la troisième fois.

左手右手慢动作

La méthode native copie directement la mémoire dans le tas

刘奇

Bien sûr que non.

à verrouiller ou à exclure mutuellement
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal