zoukankan      html  css  js  c++  java
  • Java高并发10-Unsafe类中其他方法以及测试

    一、复习

    • synchronized和volatile的不同点,相同点
    • volatile不能保证原子性,只能保证内存可见性
    • volatile在什么情况下可以使用(两种情况)
    • ABA问题定义,产生原因以及消除方法
    • Java中的CAS操作
    • unsafe类中的boolean objectFieldOffset(Field field),boolean compareAndSwapLong(Object obj,long offset,long expect,long update),int arrayBaseOffset(Class arrayClass),int arrayIndexOffset(Class arrayClass)

    二、Unsafe类中的其他方法

    1.public native long getLongvolatile(Object obj,long offset)

    • 该方法用于获取对象obj地址偏移量为offset长度的对应volatile语义的值

    2.void putLongvolatile(Object obj,long offset,long value)

    • 该方法用于在对象obj地址偏移量为offset长度的类型为long的field值设置为value,支持volatile

    3.void putOrderedLong(Object obj,long offset,long value)

    • 该方法用于在对象obj地址偏移量为offset长度的类型为long的field值设置为value,这是一个有延迟的putLongvolatile方法,并且不能保证其他线程也能看到,只有被volatile修饰并有可能被意外修改的时候才会使用这个方法

    4.void park(boolean isAbsolute,long time)

    • 如果isAbsolute为false,time=0,表示当前线程一直阻塞
    • 如果isAbsolute为false,time>0,表示当前线程阻塞time时间后,会被唤醒

    注意:这时的time是一个时间段,也就是调用开始到time用完

    • 如果isAbsolute为true,time>=0,表示当前线程time时间后阻塞停止,被唤醒,这里的time是绝对时间,会换算称ms单位的一个时间点
    • 另外当其他线程调用了该线程的nterrupt()方法之后,该线程会返回;
    • 如果其他线程调用了unpark方法,并且把该线程作为参数传入unpark方法中,那么该线程也会返回

    5.void unpark(Thread thread)

    • 唤醒调用park方法的阻塞状态的thread线程。

    6.long getAndSetLong(Object obj,long offset,long update)

    • 获取对象obj中偏移量为offset的变量volatile语义的当前值,并且设置volatile语义的值为update
    public final long getAndSetLong(Object obj,long offset,long update){
     long l;
     do{
      l=getLongvolatile(obj,offset);
     }while(!compareAndSwapLong(obj,offset,l,update);
     return l;
    }
    • 这里的循环是考虑到在多线程的环境下CAS操作会出现失败的情况,因此多次判断一下获取正确的值

    7.long getAndAddLong(Object obj,long offset,long addValue)

    • 该函数用于获取对象obj在其偏移量为offset的volatile变量的语义,并且该值赋值为原值加addValue
    public final long getAndAddLong(Object obj,long offset,long addValue){
     long l;
     do{
      l = getLongvolatile(obj,offset);
     }while(!compareAndSwapLong(obj,offset,l,l+addValue);
     return l;
    }

    三、直接对Unsafe类举例

    package com.ruigege.OtherFoundationOfConcurrent2;

    import jdk.internal.misc.Unsafe;

    public class TestUnsafe {

     static final Unsafe unsafe = Unsafe.getUnsafe();
     
     static final long state = 0;
     
     static final long stateOffset=0;
     //unsafe实例内部属性state的偏移量
     
     static {
      try {
       stateOffset = unsafe.objectFieldOffset(Unsafe.class.getDeclaredField("state"));
       
      }catch(Exception e) {
       e.printStackTrace();
      }
      
     }
     public static void main(String[] args) {
      TestUnsafe testUnsafe = new TestUnsafe();
      Boolean success = unsafe.compareAndSwapInt(testUnsafe,stateOffset,0,1);
      System.out.println(success);
     }
    }
    • 基本符合预期

    四 、源码:

  • 相关阅读:
    在VMware中为Red Hat配置静态ip并可访问网络-Windows下的VMware
    03-nginx虚拟主机配置
    解决nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
    02-nginx信号量
    RedHat Linux设置yum软件源为本地ISO
    01-nginx介绍及编译安装
    Linux.负载均衡
    01-MySQL优化大的思路
    10 华电内部文档搜索系统 search02
    10 华电内部文档搜索系统 search03
  • 原文地址:https://www.cnblogs.com/ruigege0000/p/14040074.html
Copyright © 2011-2022 走看看