作者:高档的干果ieb | 来源:互联网 | 2023-10-11 17:03
Transient是出现在mybatis映射实体类的时候,实体类某属性不需要映射的数据库表字段的时候加上transient标签。主要的作用是对象序列化的时候会忽略这个
Transient是出现在mybatis映射实体类的时候,实体类某属性不需要映射的数据库表字段的时候加上@transient标签。主要的作用是对象序列化的时候会忽略这个属性。
native在看法的过程没有使用过,在看源码的时候经常看到过用它来修饰一些方法。主要的作用在方法前加上native,代表方法是通过外部底层C实现的,调用的时候会用调用C语言方法调用。
volatile使用是在多线程开发的时候,有共享变量,使用它来就行修饰变量,注意它不能保证变量的原子性。对于读操作时:该变量拿到的一直是主内存的(最新值),主要是在多线程共享变量中,某一个线程更改变量,另一个线程有可能会从缓存中读取(优化的问题),用它可以保证变量的可见性;对于写操作时:将当前处理器缓存行的数据写回到系统内存, 这个写回内存的操作会使得在其他处理器缓存了该内存地址无效。
为什么volatile不能保持原子性:当两个线程同时操作自增的时候,取值、加值、改变内存值,由于取值跟加值都是同一个时间点,两者都还未提交修改值,内存值没有失效,然后同时提交。
添加一段代码验证volatile的可见性:
public class Test implements Runnable {/*** 内部类实现static*/static class ObjectA {private boolean flag = true;}/*** 尝试不用volatile修饰变量和用volatile修饰变量的区别*/private volatile ObjectA a;/*** 构造函数* @param a*/public Test(ObjectA a) {this.a = a;}/*** 实现线程run*/@Overridepublic void run() {while (a.flag) {//不做任何操作,或者极短的操作时间}}/*** 改变变量a的值,让线程停止的功能*/public void stop() {a.flag = false;}public static void main(String[] args) throws InterruptedException {//启动线程Test test = new Test(new ObjectA());Thread t = new Thread(test);t.start();//跑一段时间Thread.sleep(1000);//停止线程test.stop();//等待子线程停止t.join();}}
整个代码逻辑是启动一个线程,运行1秒,关闭它,当我们用volatile修饰a变量的时候,代码是没问题的,当变量改变的时候,线程马上停止;如果不用volatile修饰变量a,会发现线程一直在运行,a变量明明改变值了,但是run获取到的值一直是旧的值。