zoukankan      html  css  js  c++  java
  • Unsafe 在jdk8中与其他锁的效率对比

    unsafe 锁与在jdk8中与其他的对比

    package com.xiaodao.jdk8.thread.atomic;
    
    import com.sun.webkit.dom.CounterImpl;
    import sun.misc.Unsafe;
    
    import java.lang.reflect.Field;
    import java.util.concurrent.Executor;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.atomic.AtomicInteger;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * @Created by xiaodao
     */
    public class UnsafeTest {
    
        /***
         * stupidcounter       result = 9111265     time passed  =   233
         *sync counter:counter result = 10000000   time passed  =   633
         *lockCounter: counter result = 10000000   time passed  =   365
         * atomic counter result = 10000000        time passed  =   324
         *cas counter : counter result = 10000000    time passed  =   1645
         * 
         *
         * @param args
         * @throws InterruptedException
         */
        public static void main(String[] args) throws InterruptedException, NoSuchFieldException {
    
            ExecutorService service = Executors.newFixedThreadPool(1000);
            Counter counter= new CasCounter();
            long starTiem  = System.currentTimeMillis();
            for (int i = 0; i <1000 ; i++) {
                service.submit(new CounterRun(counter,10000));
            }
            //线程池停止了.但是还是在运行 .在等10分钟.
            service.shutdown();
            service.awaitTermination(10, TimeUnit.MINUTES);
            long endTiem  = System.currentTimeMillis();
    
            System.out.println("counter result = " + counter.getCounter());
            System.out.println("time passed  =   "+ (endTiem-starTiem));
    
        }
    
        public static Unsafe getUnsafe(){
            try {
                Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
                theUnsafe.setAccessible(true);
                return (Unsafe)theUnsafe.get(null);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
        interface  Counter{
            void increment();
            long getCounter();
        }
    
        /**
         * 实现类.
         */
       static class StupidCounter implements  Counter{
    
            private  long counter = 0;
            @Override
            public void increment() {
    
                counter++;
            }
    
            @Override
            public long getCounter() {
                 return counter;
            }
        }
    
        static class SyncCounter implements  Counter{
    
            private  long counter = 0;
            @Override
            public  synchronized  void increment() {
    
                counter++;
            }
    
            @Override
            public long getCounter() {
                return counter;
            }
        }
    
        static class LockCounter implements  Counter{
    
           private static Lock lock = new ReentrantLock();
            private  long counter = 0;
            @Override
            public   void increment() {
    
                try {
                    lock.lock();
                    counter++;
                } finally {
                    lock.unlock();
                }
            }
    
            @Override
            public long getCounter() {
                return counter;
            }
        }
    
        /**
         * atomic
         */
        static class AtomicCounter implements  Counter{
    
            private AtomicInteger counter = new AtomicInteger();
            @Override
            public void increment() {
    
                counter.incrementAndGet();
            }
    
            @Override
            public long getCounter() {
                return counter.get();
            }
        }
        /***
         *
         */
    
        static class CasCounter implements  Counter{
    
            private volatile long counter = 0;
    
            private  Unsafe unsafe;
            private long offset;
    
            public CasCounter() throws NoSuchFieldException {
                unsafe=getUnsafe();
                //.get offset
                offset =  unsafe.objectFieldOffset(CasCounter.class.getDeclaredField("counter"));
    
            }
    
            @Override
            public void increment() {
                long current = counter;
                while(!unsafe.compareAndSwapLong(this,offset,current,current+1)){
    
                    current =  counter;
                }
            }
    
            @Override
            public long getCounter() {
                return counter;
            }
        }
        /**
         * fang放在线程池里跑的类.
         */
     static   class CounterRun implements Runnable{
    
            private final Counter counter;
            private int num ;
    
         public CounterRun(Counter counter, int num) {
             this.counter = counter;
             this.num = num;
         }
    
         public Counter getCounter() {
             return counter;
         }
    
         public int getNum() {
             return num;
         }
    
         public void setNum(int num) {
             this.num = num;
         }
    
         @Override
           public void run() {
             for (int i = 0; i <num ; i++) {
                 counter.increment();
    
             }
    
           }
       }
    }


     * stupidcounter        result = 9111265     time passed  =   233
      *sync counter:counter  result = 10000000    time passed  =   633
      *lockCounter: counter  result = 10000000    time passed  =   365
      * atomic counter       result = 10000000    time passed  =   324
      *cas counter : counter result = 10000000    time passed  =   1645
     

    最终测试:

    unsafe可以做哪些事情呢?

    unsafe. 直接调用cpu缓存 c++ 汇编指令

    跳过构造器直接创建类

    public class UnsafefooTest {
        public static void main(String[] args) throws InstantiationException, ClassNotFoundException, IllegalAccessException {
    
    
            Unsafe unsafe = getUnsafe();
            //unsafe 可以做一些邪恶的操作(直接开辟一个内存) 直接绕过构造方法创建对象.
            Simple o = (Simple) unsafe.allocateInstance(Simple.class);
    
    //        System.out.println(o.get());
    //        System.out.println(o.getClass());
    //        System.out.println(o.getClass().getClassLoader());
        }
    
        public static Unsafe getUnsafe(){
            try {
                Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
                theUnsafe.setAccessible(true);
                return (Unsafe)theUnsafe.get(null);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    
    
        static  class Simple{
            private int l =0;
    
            public Simple(int l) {
                this.l = 1;
    
                System.out.println("=========");
            }
    
            public int get(){
                return l;
            }
        }
    
    }
    View Code

    直接将对象的某个内存赋值

        static class Simple1{
            private  int ACCESS_ALLOWED = 1;
            private boolean allow(){
                return 40 == ACCESS_ALLOWED;
            }
    
    
            public void work(){
                if(allow()){
                    System.out.println("i'm working by allowed ........");
                }
            }
    
        }
    
    
     Simple1 simple1 = new Simple1();
            Field access_allowed = simple1.getClass().getDeclaredField("ACCESS_ALLOWED");
            unsafe.putInt(simple1,unsafe.objectFieldOffset(access_allowed),40);
            simple1.work();

    然后下面的代码就可以执行...

    部分底层代码如何调用的呢?

    我们来看下unsafe.class 底层代码如何的,就用atomicInteger 来讲

        public final boolean compareAndSet(int expect, int update) {
            return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
        }

    jvm atomic.app 来做一些判断

    1.首先判断 cpu是否是多核的 如果是加一个lock1 内存屏障 volatile 

    2.进行对比交换.是调用的汇编指令 cmpchg1

    3.asm(汇编指令)

  • 相关阅读:
    Keras猫狗大战四:数据增强+添加dropout层,精度达83%
    Keras猫狗大战三:加载模型,预测目录中图片,画混淆矩阵
    左边列表多选可以批量移动到右边列表,右边列表页可以批量移动到左边列表,可以实现前端自动搜索 ajax 传递List
    两个list框联动-转载
    mybatis
    lambda
    sprint 单元测试
    java项目部署测试服务器二级域名解决方案
    java cookie 单点登录和登录拦截器 从实现到原理
    redis 概述和阿里云redis搭建和java后台获取
  • 原文地址:https://www.cnblogs.com/bj-xiaodao/p/10816753.html
Copyright © 2011-2022 走看看