RSA 优化 的原理详解 ,synchronized的使用

一、 原来代码

  • 示例代码:

       private static org.bouncycastle.jce.provider.BouncyCastleProvider bouncyCastleProvider = null;
       public static  org.bouncycastle.jce.provider.BouncyCastleProvider getBouncyCastleProviderInstance() {
           if (bouncyCastleProvider == null) {
               bouncyCastleProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
           }
           return bouncyCastleProvider;
       }
    

二、 优化后代码

  • 示例代码:

      private static  volatile org.bouncycastle.jce.provider.BouncyCastleProvider bouncyCastleProvider ;
      public static  org.bouncycastle.jce.provider.BouncyCastleProvider getBouncyCastleProviderInstance() {
          if (bouncyCastleProvider == null) {
              synchronized(org.bouncycastle.jce.provider.BouncyCastleProvider.class){
                  if(bouncyCastleProvider == null){
                      bouncyCastleProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
                  }
              }
          }
          return bouncyCastleProvider;
      }
    

三、实现原理

  • 添加synchronized关键字。添加到同步代码块中,而不是如下:

    public static synchronized org.bouncycastle.jce.provider.BouncyCastleProvider getBouncyCastleProviderInstance() {
        if (bouncyCastleProvider == null) {
            bouncyCastleProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
        }
        return bouncyCastleProvider;
     }
    
  • 目的:即:保证在同一时刻最多只有一个线程执行该段代码,达到保证并发安全的效果。

四 、 synchronized

  • 定义
    • synchronized锁是重量级锁,重量级体现在活跃性差一点。synchronized锁是内置锁,意味着JVM能基于synchronized锁做一些优化:比如增加锁的粒度(锁粗化)、锁消除。
    • synchronized锁释放是自动的,当线程执行退出synchronized锁保护的同步代码块时,会自动释放synchronized锁。
    • 线程在竞争synchronized锁时是非公平的。
  • synchronized Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
    1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
    2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
    3. 修饰一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
    4. 修饰一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
  • 使用
    • 1、 普通同步方法,锁的是当前实例的对象

      • 同步方法锁住的是调用方法的对象;新创建的对象调用方法,和之前的方法不同步。
         class mYread implements Runnable {
            private static int count;
            public mYread() {
               count = 0;
            }
            public synchronized  void method() {
               for (int i = 0; i < 5; i ++) {
                  try {
                     System.out.println(Thread.currentThread().getName() + ":" + (count++));
                     Thread.sleep(100);
                  } catch (InterruptedException e) {
                     e.printStackTrace();
                  }
               }
            }
            public synchronized void run() {
               method();
            }
         }
         //执行调用
          mYread read1 = new mYread();
          mYread read2 = new mYread();
          Thread thread1 = new Thread(read1, "mYread1");
          Thread thread2 = new Thread(read2, "mYread2");
          thread1.start();
          thread2.start();
          
          read1 和 read2 是两个对象,thread1和thread2执行不会保持线程同步。
       ```
    -  2、 静态同步方法,锁的是静态方法所在的类对象
      
      - 静态同步方法锁的是类的对象,新创建的对象也是被锁的对象。
    
    
     class mYread implements Runnable {
        private static int count;
        public mYread() {
           count = 0;
        }
        public synchronized static void method() {
           for (int i = 0; i < 5; i ++) {
              try {
                 System.out.println(Thread.currentThread().getName() + ":" + (count++));
                 Thread.sleep(100);
              } catch (InterruptedException e) {
                 e.printStackTrace();
              }
           }
        }
        public synchronized void run() {
           method();
        }
     }
     //执行调用
      mYread read1 = new mYread();
      mYread read2 = new mYread();
      Thread thread1 = new Thread(read1, "mYread1");
      Thread thread2 = new Thread(read2, "mYread2");
      thread1.start();
      thread2.start();
      
      read1 和 read2 是两个对象,但在thread1和thread2并发执行时却保持了线程同步。
     ```
    
    • 3、 同步代码块,锁的是括号里的对象。(此处的可以是实例对象,也可以是类的class对象。)
    1. 指定给某个对象加锁

      如果有一个明确的对象:

        public abstract class RSACoderUtils extends CoderUtils {
           if (bouncyCastleProvider == null) { 
               synchronized(org.bouncycastle.jce.provider.BouncyCastleProvider.class){
                   if(bouncyCastleProvider == null){
                       bouncyCastleProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
                   }
               }
           }
        }
      

      如果没有一个明确的对象:

         public abstract class RSACoderUtils extends CoderUtils {
            if (bouncyCastleProvider == null) { 
                private byte[] lock = new byte[0];  // 特殊的instance变量         
                synchronized(lock){
                       if(bouncyCastleProvider == null){
                           bouncyCastleProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
                       }
                 }
            }
         }            
      

      -. 比较两种创建对象的消耗:

           Object lock = new Object();
           private byte[] lock = new byte[0];
      

      通过查看编译后的字节码:生成零长度的byte[]的lock需要3行操作码,Object 的lock 则需要7行操作码,故零长度的byte数组对象创建性能更好。

    2. 给某个类加锁

           public abstract class RSACoderUtils extends CoderUtils {
              public void test(){
                  synchronized(RSACoderUtils.class){
                      if(bouncyCastleProvider == null){
                          bouncyCastleProvider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
                      }
                  }
              }
           }
      

五、volatile

  • 禁止指令重排序优化
  • 保证此变量对所有线程的可 见性,这里的“可见性”是指当一条线程修改了这个变量的值,新值对于其他线程来说是可以 立即得知的。

六、 单例模式

  • 保证一个类仅有一个实例,并提供一个访问它的全局访问点。
  • 懒汉模式 :
	public class Monitor {
		   private static Monitor monitor = null;
		   private static volatile Monitor monitor = null;   //
		       private Monitor() {}
			public static Monitor getMonitor() {
				   if (monitor == null) {
					       synchronized (Monitor.class) {
					           if (monitor == null) {
					               monitor = new Monitor();
					           } 
					       }
				   }
				   return monitor;
			}
}
  • 饿汉模式:
 public class Monitor {
        private static Monitor monitor = new Monitor ();
        private  Monitor () {}
        public static Monitor getMonitor() {
            return monitor;
        }
 }

更多内容,阿里博客地址:
https://yq.aliyun.com/users/article?spm=a2c4e.11153940.headeruserinfo.3.2b9f291a9z4pJ7
欢迎关注公众号,查看更多内容 :
volatile 关键字的详细介绍;
synchronized 关键字的详解;
XG54_9_WXMH_5X_HB_H_7V

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值