public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
And native 方法和线程安全之间又没有什么必然联系, 并且我看 System.arraycopy 的文档中也没有提到它是线程安全的, 因此就可以知道它是 线程不安全的.
But in order to verify whether System.arraycopy is really thread-unsafe, I wrote a small example:
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();
}
}
The specific operation of this example is:
arrayOriginal and arraySrc are the same when initialized, while arrayDist is all zeros.
Start a thread to run the copy() method to copy arraySrc to arrayDist.
Execute the modify() operation in the main thread to modify the contents of arraySrc. In order to ensure that the modify() 操作, 修改 arraySrc 的内容. 为了确保 copy() 操作先于 modify() operation precedes the modify() operation, I use Condition and delay it for two milliseconds, to ensure that the copy operation (i.e. System.arraycopy) is executed before the modification operation.
According to the third point, if System.arraycopy 是线程安全的, 那么先执行拷贝操作, 再执行修改操作时, 不会影响复制结果, 因此 arrayOriginal 必然等于 arrayDist; 而如果 System.arraycopy 是线程不安全的 is thread-safe, then performing the copy operation first and then performing the modification operation will not affect the copy result, so arrayOriginal must be equal to arrayDist; and if
is thread-safe, then arrayOriginal is not equal to arrayDist.
Based on the above reasoning, run the program and get the following output:
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)
You can see that the first two times it worked fine, but the third time it didn’t work.🎜
System.arraycopy
是一个native
Method:And
native
方法和线程安全之间又没有什么必然联系, 并且我看System.arraycopy
的文档中也没有提到它是线程安全的, 因此就可以知道它是线程不安全的
.But in order to verify whether
System.arraycopy
is really thread-unsafe, I wrote a small example:The specific operation of this example is:
arrayOriginal and arraySrc are the same when initialized, while arrayDist is all zeros.
Start a thread to run the
copy()
method to copy arraySrc to arrayDist.Execute the
modify()
operation in the main thread to modify the contents of arraySrc. In order to ensure that themodify()
操作, 修改 arraySrc 的内容. 为了确保copy()
操作先于modify()
operation precedes themodify()
operation, I use Condition and delay it for two milliseconds, to ensure that the copy operation (i.e. System.arraycopy) is executed before the modification operation.According to the third point, if
isSystem.arraycopy
是线程安全的, 那么先执行拷贝操作, 再执行修改操作时, 不会影响复制结果, 因此 arrayOriginal 必然等于 arrayDist; 而如果System.arraycopy
是线程不安全的
is thread-safe, then performing the copy operation first and then performing the modification operation will not affect the copy result, so arrayOriginal must be equal to arrayDist; and ifthread-safe, then arrayOriginal is not equal to arrayDist.
native method directly copies the memory in the heap
Of course not. To be locked or mutually exclusive