当前位置:网站首页>Unsafe and CAS principle
Unsafe and CAS principle
2022-07-03 22:42:00 【xmh-sxh-1314】
JavaDoc say , Unsafe Provides a set of for executing the underlying , Method of unsafe operation . So what are the specific methods , I drew a picture .
Unsafe Methods classification
You can see Unsafe Provided in CAS, Memory operations , Thread scheduling , Native information ,Class Related methods , View and set an object or field , Memory allocation and release related operations , Memory address acquisition related methods . I took the time to comment on the above methods ,
You can see it here .
So how to use Unsafe Well ? Now let's talk about how to get Unsafe And operate .
1. obtain Unsafe example
As follows , because Unsafe.getUnsafe It will judge whether the class loader of the calling class is the boot class loader , If it is , You can get Unsafe example , Otherwise, a security exception will be thrown .
@CallerSensitive
public static Unsafe getUnsafe() {
Class var0 = Reflection.getCallerClass();
if (!VM.isSystemDomainLoader(var0.getClassLoader())) {
throw new SecurityException("Unsafe");
} else {
return theUnsafe;
}
}
There are two main ways to bypass security checks , One is by using Unsafe Give your class to bootstrap class loader To load the , Another way is through reflection .
1.1 adopt bootstrap class loader To load the Unsafe.
public class GetUnsafeFromMethod {
public static void main(String[] args){
// Call this method , You must get , Otherwise, a security exception will be thrown
Unsafe unsafe = Unsafe.getUnsafe();
System.out.printf("addressSize=%d, pageSize=%d\n", unsafe.addressSize(), unsafe.pageSize());
}
}
Above code , Direct execution will report security exception SecurityException, The reason is that at present caller The class loader of is the application class loader (Application Class loader), What is required is to start the class loader ,
thus !VM.isSystemDomainLoader(var0.getClassLoader()) return false, Throw an exception .
But through the following command line , We put GetUnsafeFromMethod.java Append to bootclasspath( Start class loading path ) On , Then it can be executed normally .
javac -source 1.8 -encoding UTF8 -bootclasspath "%JAVA_HOME%/jre/lib/rt.jar;." GetUnsafeFromMethod.java
java -Xbootclasspath:"%JAVA_HOME%/jre/lib/rt.jar;." GetUnsafeFromMethod
As you can see, it's a little troublesome , Is it difficult to add such a large series of instructions every time you start , So let's see if reflection is easier to use .
1.2 Get by reflection Unsafe
import sun.misc.Unsafe;
import java.lang.reflect.Field;
public class GetUnsafeFromReflect {
public static void main(String[] args){
Unsafe unsafe = getUnsafe();
System.out.printf("addressSize=%d, pageSize=%d\n", unsafe.addressSize(), unsafe.pageSize());
}
public static Unsafe getUnsafe() {
Unsafe unsafe = null;
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
unsafe = (Unsafe) f.get(null);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return unsafe;
}
}
Um. , You can use it directly through reflection , Is it much better than the previous method of loading by using the boot class loader
3.Unsafe API Use
How to use it , Check out this article .
Practical application cases , You can check an article by meituan .
4. Unsafe in CAS Partial implementation
We can see Unsafe Basically, they call native Method , If you are curious about this native How is the method implemented , Then you need to go JVM Find the corresponding implementation .
To http://hg.openjdk.java.net/ Choose the corresponding... Step by step hotspot edition , Here's what I downloaded http://hg.openjdk.java.net/jdk8u/jdk8u60/hotspot/archive/tip.tar.gz,
Then solve hotspot Catalog , Find out \src\share\vm\prims\unsafe.cpp, This is the corresponding jvm dependent c++ Implementation class .
So let's say we're talking about CAS Partial implementation is of great interest , You can search in this file compareAndSwapInt, You can see the corresponding JNI Method is Unsafe_CompareAndSwapInt
// These are the methods prior to the JSR 166 changes in 1.6.0
static JNINativeMethod methods_15[] = {
...
{CC"compareAndSwapObject", CC"("OBJ"J"OBJ""OBJ")Z", FN_PTR(Unsafe_CompareAndSwapObject)},
{CC"compareAndSwapInt", CC"("OBJ"J""I""I"")Z", FN_PTR(Unsafe_CompareAndSwapInt)},
{CC"compareAndSwapLong", CC"("OBJ"J""J""J"")Z", FN_PTR(Unsafe_CompareAndSwapLong)}
...
};
Then we are searching Unsafe_CompareAndSwapInt The implementation of the ,
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
UnsafeWrapper("Unsafe_CompareAndSwapInt");
oop p = JNIHandles::resolve(obj); // Find the object to specify
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset); // Get the memory address of the field of the object to be operated .
return (jint)(Atomic::cmpxchg(x, addr, e)) == e; // perform Atomic Class cmpxchg.
UNSAFE_END
You can see that it will finally call Atomic::cmpxchg Functions inside , This depends on different operating systems and CPU There will be different implementations , But it's all on hotspot\src\os_cpu Under the table of contents , such as linux_64x Of , The corresponding class is hotspot\src\os_cpu\linux_x86\vm\atomic_linux_x86.inline.hpp, and windows_64x Of , The corresponding class is hotspot\src\os_cpu\windows_x86\vm\atomic_windows_x86.inline.hpp.( Here also explains why Java Sure Write once, Run everywhere, The reason is that JVM The source code is different for different operating systems and CPU There are different implementations )
Here we have linux_64x As an example of , see Atomic::cmpxchg The implementation of the
inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
int mp = os::is_MP();
__asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
: "=a" (exchange_value)
: "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
: "cc", "memory");
return exchange_value;
}
0.os::is_MP
os::is_MP() stay hotspot\src\share\vm\runtime\os.hpp in , as follows :
// Interface for detecting multiprocessor system
static inline bool is_MP() {
// During bootstrap if _processor_count is not yet initialized
// we claim to be MP as that is safest. If any platform has a
// stub generator that might be triggered in this phase and for
// which being declared MP when in fact not, is a problem - then
// the bootstrap routine for the stub generator needs to check
// the processor count directly and leave the bootstrap routine
// in place until called after initialization has ocurred.
return (_processor_count != 1) || AssumeMP;
}
1.__asm__: Indicates that the next step is inline assembly code , Use here asm Statement can contain assembly instructions directly in C In the code , Mainly for the ultimate performance .
2.volatile: It means removing optimization
3.LOCK_IF_MP Is a macro definition , namely :#define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
Substitution text
边栏推荐
- How to solve the problem of requiring a password when accessing your network neighborhood on your computer
- [actual combat record] record the whole process of the server being attacked (redis vulnerability)
- Leetcode: a single element in an ordered array
- Yyds dry goods inventory Prometheus alarm Art
- Is it safe and reliable to open an account and register for stock speculation? Is there any risk?
- To rotate 90 degrees clockwise and modify the video format
- STM32 multi serial port implementation of printf -- Based on cubemx
- [sg function] 2021 Niuke winter vacation training camp 6 h. winter messenger 2
- The reason why the computer runs slowly and how to solve it
- In 2022, 6G development has indeed warmed up
猜你喜欢
Unique in China! Alibaba cloud container service enters the Forrester leader quadrant
How the computer flushes the local DNS cache
Firefox set up proxy server
How to solve win10 black screen with only mouse arrow
Blue Bridge Cup -- Mason prime
Awk getting started to proficient series - awk quick start
Teach you to easily learn the type of data stored in the database (a must see for getting started with the database)
Data consistency between redis and database
Teach you how to run two or more MySQL databases at the same time in one system
Weekly leetcode - nc9/nc56/nc89/nc126/nc69/nc120
随机推荐
[dynamic planning] counting garlic customers: the log of garlic King (the longest increasing public subsequence)
[dynamic programming] Ji Suan Ke: Suan tou Jun breaks through the barrier (variant of the longest increasing subsequence)
The difference between SRAM and DRAM
[Android reverse] use DB browser to view and modify SQLite database (download DB browser installation package | install DB browser tool)
Is it safe and reliable to open an account and register for stock speculation? Is there any risk?
2022 safety officer-a certificate registration examination and summary of safety officer-a certificate examination
File copy method
Blue Bridge Cup Guoxin Changtian single chip microcomputer -- led lamp module (V)
Pat grade A - 1164 good in C (20 points)
Label coco format data and format data in the upper left corner and lower right corner are mutually converted
Xiangong intelligent obtained hundreds of millions of yuan of b-round financing to accelerate the process of building non-standard solutions with standardized products
C3p0 connection MySQL 8.0.11 configuration problem
How can enterprises and developers take advantage of the explosion of cloud native landing?
AST (Abstract Syntax Tree)
Ansible common usage scenarios
3 environment construction -standalone
Druids connect to mysql8.0.11
Classification and extension of OC
Preliminary analysis of smart microwave radar module
How about agricultural futures?