16、使用VarHandle
这个和15一样。
我感觉太复杂了,文档很长。。。所以采用最低标准(把书上的练习做了。。)
先看文档
两个内部类,先放着
accessModeType()涉及到内部类,先放着
acquireFence(),没看懂什么意思
java9系列(七)Variable Handles
这篇博客说:
很明显,我Unsafe干嘛用的都不知道,更不清楚JVM的内存模型,和内存可见性,指令重排序。。。。
找了一个说Unsage的博客
说一说Java的Unsafe类
感觉非常复杂
fence这个单词在这里的和内存屏障有关系,但是我都不知道内存屏障是什么
通过这篇博客来看:java内存屏障的原理与应用
内存屏障和指令重新排序有关系(防止硬件错误的优化),进而也和线程之间的同步和互斥有关系。是一种更加底层的描述,很多方法,比如:java的synchronized和volatile都是通过内存屏障实现。
compareAndExchange()看不懂,不知道怎么用,网上也没查到。。。模仿疯狂上的例子,写一个
懂了一点,返回值是,指定位置的值,其实效果和输入参数都和compareAndSet(String[],2,"","")非常相似,只是返回值是指定位置的数组元素,而不是true或者false
compareAndExchangeAcquire() 和compareAndExchange()类似,不过不知道这个Acquire的含义
compareAndExchangeRelease() 和compareAndExchange()类似,不过不知道这个Release的含义
compareAndSet()
coordinateTypes()说什么,返回坐标,看不太懂。。。String[].class的VarHandle返回值如下:
describeConstable()这个方法找不到了,可能被移除了。确实。下面是最新版的java文档,里面确实没有这个方法
Java文档
fullFence()也看不懂。。。:就是这个屏障之前的读取和写入操作的机器码不会和这个屏障之后的读取和写入操作的机器码进行重新排序,会保持原有顺序。
get()
getAcquire() 这里Acquire的意思可以被上面的compareAndExchangeAcquire()借鉴
getAndAdd(cat,0);不知道为什么会报错,但是用法应该是这样,网上搜不到。我懂了,这是针对数字类型的,第二个参数,是加上的数
getAndAddAcquire(cat,1) 针对数字
getAndAddRelease(cat,2) 针对数字
getAndBitwiseAnd(cat,4) 返回值是get()方法得到的值,然后后面的4则会与对应的变量进行按位与,并且改变那个变量的值。所以应该这么解读这个函数。get() And BitwiseAnd()
getAndBitwiseAndAcquire(cat,4)同上
getAndBitwiseAndRelease(cat , 4) 同上
getAndBitwiseOr(cat, 1) 返回的是类中的原值,然后后面的1会和对应的变量进行按位或,并且改变变量的值。
getAndBitwiseOrAcquire()同上
getAndBitwiseOrRelease()同上
getAndBitwiseXor(cat, 2) 返回的是类中的变量原值,然后后的2会和对应的变量进行按位异或,并且改变类中变量的值
getAndBitwiseXorAcquire(cat,4) 同上
getAndBitwiseXorRelease(cat,8) 同上
关于Acquire和Release的解释是这样的,具体的效果不清楚
Acquire的含义: 屏障之前的读取不会和屏障之后的读取和写入的机器码重排序
Release的含义:屏障之前的读取和写入不会和屏障之后的写入的机器码重排序
但不知道acquireFence()和releaseFence()怎么用,就是放在语句中间吗?
我想知道这里的Acquire和Release的含义,Acquire是说,代码执行顺序在执行这个方法之前不会被调整顺序?Release的含义是代码执行顺序在执行这个方法之后不会被调整顺序吗?
文档上的加载和存储是什么意思?答:load是读取,store是写入的意思。
maven构建多个包的项目。之前没有想到过,现在感觉好像不行…
getAndSet()
getAndSetAcquire()
getAndSetRelease()
getOpaque()不理解
getValidate()
isAccessModeSupported()涉及到两个内部类,先放着
JVM内存模型、指令重排、内存屏障概念解析
loadLoadFence()
releaseFence()
set()
setOpaque()
setRelease()
setVolatile()
toMethodHandle()涉及到内部类,先放着
varType()
weakCompareAndSet()
weakCompareAndSetAcquire()
weakCompareAndSetPlain() 这里的Plian不理解
weakCompareAndSetRelease()
以下是练习代码:
import java.util.*;
import java.io.*;
import java.lang.invoke.*;
public class Test
{
public static void main(String[] args) throws Exception,Throwable
{
//VarHandle
//书上的练习
String[] sa = new String[] {"Java","Kotlin","Go"};
//获取一个String[]数组的VarHandle
VarHandle avh = MethodHandles.arrayElementVarHandle(String[].class);
//比较并设置:如果第三个元素是Go,则该元素被设为Lua
boolean r = avh.compareAndSet(sa,2,"Go","Lua");
//输出比较结果
System.out.println(r);
//看到第三个元素被替换成Lua
System.out.println(Arrays.toString(sa));
//获取sa数组的第二个元素
System.out.println(avh.get(sa,1));//输出Kotlin
//获取并设置:返回第三个元素,并将第三个元素设为Swift
System.out.println(avh.getAndSet(sa,2,"Swift"));
//看到第三个元素被替换成Swift
System.out.println(Arrays.toString(sa));
//用findVarHandle方法获取User类中名为name、
//类型为String的实例变量
VarHandle vh1 = MethodHandles.lookup().findVarHandle(User.class,"name",String.class);
User user = new User();
//通过VarHandle获取实例变量的值,需要传入对象作为调用者
System.out.println(vh1.get(user));//输出null
// 通过VarHnadle设置指定实例变量的值
vh1.set(user,"孙悟空");
//输出user的name实例变量的值
System.out.println(user.name); //输出孙悟空
//用findVarHandle方法获取User类中名为MAX_AGE
//类型为Integer的类变量
VarHandle vh2 = MethodHandles.lookup().findStaticVarHandle(User.class,
"MAX_AGE",int.class);
//通过VarHandle获取指定类变量的值
System.out.println(vh2.get());
//通过VarHandle设置指定类变量的值
vh2.set(100);
//输出User的MAX_AGE类变量
System.out.println(User.MAX_AGE);//输出100
//一个小练习
VarHandle dog_name = MethodHandles.lookup().findVarHandle(Dog.class,
"name",String.class);
Dog dog = new Dog();
System.out.println(dog_name.get(dog));
dog_name.set(dog,"旺财");
System.out.println(dog_name.get(dog));
VarHandle dog_color = MethodHandles.lookup().findStaticVarHandle(Dog.class,"color",String.class);
System.out.println(dog_color.get());
dog_color.set("白色");
System.out.println(dog_color.get());
//java文档
//方法
VarHandle.acquireFence();
System.out.println();
String[] names = {"小强","小白","小刚"};
//获取一个String[]数组的VarHandle对象
VarHandle vh = MethodHandles.arrayElementVarHandle(String[].class);
String something =(String) vh.compareAndExchange(names,2,"小刚","bb");
System.out.println(something);
System.out.println(Arrays.toString(names));
vh = MethodHandles.arrayElementVarHandle(String[].class);
something =(String) vh.compareAndExchangeAcquire(names,0,"小强","(●—●)");
System.out.println(something);
System.out.println(Arrays.toString(names));
vh = MethodHandles.arrayElementVarHandle(String[].class);
something = (String) vh.compareAndExchangeRelease(names,1,"小白","66");
System.out.println(something);
System.out.println(Arrays.toString(names));
vh = MethodHandles.arrayElementVarHandle(String[].class);
boolean done = vh.compareAndSet(names,1,"66","77");
System.out.println(done);
System.out.println(Arrays.toString(names));
System.out.println(vh.coordinateTypes());
//System.out.println(vh.describeConstable());
VarHandle.fullFence();
vh = MethodHandles.lookup().
findVarHandle(Cat.class,"name",String.class);
Cat cat = new Cat();
cat.name = "小白";
System.out.println(vh.get(cat));
System.out.println(vh.getAcquire(cat));
vh = MethodHandles.lookup().findVarHandle(Cat.class,"age",int.class);
System.out.println((int)vh.getAndAdd(cat,1));
System.out.println((int)vh.getAndAddAcquire(cat,2));
System.out.println((int)vh.getAndAddRelease(cat,3));
vh = MethodHandles.lookup().findVarHandle(Cat.class,"bb", int.class);
System.out.println((int)vh.getAndBitwiseAnd(cat,6));
System.out.println(vh.get(cat));
System.out.println((int)vh.getAndBitwiseAndAcquire(cat,7));
System.out.println(vh.get(cat));
System.out.println((int)vh.getAndBitwiseAndRelease(cat,2));
System.out.println(vh.get(cat));
vh = MethodHandles.lookup().findVarHandle(Cat.class,"or",int.class);
System.out.println((int) vh.getAndBitwiseOr(cat,1));
System.out.println(vh.get(cat));
System.out.println((int) vh.getAndBitwiseOrAcquire(cat,4));
System.out.println(vh.get(cat));
System.out.println((int) vh.getAndBitwiseOrRelease(cat,8));
System.out.println(vh.get(cat));
vh = MethodHandles.lookup().findVarHandle(Cat.class, "xor",int.class);
System.out.println((int)vh.getAndBitwiseXor(cat,2));
System.out.println(vh.get(cat));
System.out.println((int)vh.getAndBitwiseXorAcquire(cat,4));
System.out.println(vh.get(cat));
System.out.println((int)vh.getAndBitwiseXorRelease(cat,8));
System.out.println(vh.get(cat));
vh = MethodHandles.lookup().findVarHandle(Cat.class,"test",int.class);
System.out.println((int) vh.getAndSet(cat,18));
System.out.println(vh.get(cat));
vh = MethodHandles.lookup().findVarHandle(Cat.class,"type",String.class);
System.out.println((String) vh.getAndSet(cat,"伍德家"));
System.out.println(vh.get(cat));
System.out.println((String) vh.getAndSetAcquire(cat,"溜溜"));
System.out.println(vh.get(cat));
System.out.println((String) vh.getAndSetRelease(cat,"灌篮高手"));
System.out.println(vh.get(cat));
System.out.println(vh.getOpaque(cat));
System.out.println(vh.getVolatile(cat));
VarHandle.loadLoadFence();
VarHandle.releaseFence();
vh = MethodHandles.lookup().findVarHandle(Cat.class,"roam",String.class);
System.out.println(vh.get(cat));
vh.set(cat,"吼吼");
System.out.println(vh.get(cat));
vh.setOpaque(cat,"哞哞");
System.out.println(vh.get(cat));
vh.setRelease(cat,"啾啾");
System.out.println(vh.get(cat));
vh.setVolatile(cat,"汪汪");
System.out.println(vh.get(cat));
VarHandle.storeStoreFence();
System.out.println(vh.varType());
System.out.println(vh.weakCompareAndSet(cat,"汪汪","喵喵"));
System.out.println(vh.get(cat));
System.out.println(vh.weakCompareAndSetAcquire(cat,"秒","汪汪"));
System.out.println(vh.get(cat));
System.out.println(vh.weakCompareAndSetPlain(cat,"哈哈","666"));
System.out.println(vh.get(cat));
System.out.println(vh.weakCompareAndSetRelease(cat,"喵喵","牛牛"));
System.out.println(vh.get(cat));
}
}
class User
{
String name;
static int MAX_AGE;
}
class Dog
{
String name;
static String color;
}
class Cat
{
String name;
String color;
int age = 10;
int bb = 4;
int or = 2;
int xor = 1;
int test = 10;
String type = "流浪";
String roam = "喵喵";
}