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 :
arrayOriginal et arraySrc sont identiques une fois initialisés, tandis que arrayDist est entièrement composé de zéros.
Démarrez un fil de discussion pour exécuter la méthode copy() pour copier arraySrc dans arrayDist.
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.
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.
System.arraycopy
est une méthodenative
: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 deSystem.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 :Le fonctionnement spécifique de cet exemple est :
arrayOriginal et arraySrc sont identiques une fois initialisés, tandis que arrayDist est entièrement composé de zéros.
Démarrez un fil de discussion pour exécuter la méthode
copy()
pour copier arraySrc dans arrayDist.exécute l'opération
modify()
dans le thread principal et modifie le contenu de arraySrc Afin de m'assurer que l'opérationcopy()
précède l'opérationmodify()
, 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.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 :
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