当前位置: 首页 > news >正文

房屋平面图在线制作网站公司虚拟地址多少钱一年

房屋平面图在线制作网站,公司虚拟地址多少钱一年,莆田市网站建设,网站单页发布目录 异步回调JMM 理解对 volatile 的理解1、保证可见性2、不保证原子性3、禁止指令重排 对 JMM 的理解 详解单例模式饿汉式懒汉式DCL懒汉式#xff1a;双重检测锁模式的懒汉式单例静态内部类实现单例通过反射破坏单例#xff0c;修改后的DCL饿汉式枚举实现单例防止反射破坏 … 目录 异步回调JMM 理解对 volatile 的理解1、保证可见性2、不保证原子性3、禁止指令重排 对 JMM 的理解 详解单例模式饿汉式懒汉式DCL懒汉式双重检测锁模式的懒汉式单例静态内部类实现单例通过反射破坏单例修改后的DCL饿汉式枚举实现单例防止反射破坏 理解 CAScompareAndSwapCAS 出现的 ABA 问题理解 ABA 问题解决 ABA 问题带版本号的原子操作、乐观锁思想 公平锁非公平锁可重入锁递归锁自旋锁排除死锁 异步回调 Future 设计的初衷 对将来的某个事件的结果进行建模 没有返回值的 runAsync 异步回调 import java.util.concurrent.*;/*** 异步调用 CompletableFuture* 异步执行* 成功回调* 失败回调*/ public class test {public static void main(String[] args) throws ExecutionException, InterruptedException {//发起一个请求 void// 没有返回值的 runAsync 异步回调CompletableFutureVoid completableFuture CompletableFuture.runAsync(() - {try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() runAsyncvoid);});System.out.println(11111111);completableFuture.get();//获取执行结果} }有返回值的异步回调 supplyAsync import java.util.concurrent.*;/*** 异步调用 CompletableFuture* 异步执行* 成功回调* 失败回调*/ public class test {public static void main(String[] args) throws ExecutionException, InterruptedException {// completableFuture.get(); // 获取阻塞执行结果// 有返回值的 supplyAsync 异步回调// ajax成功和失败的回调// 失败返回的是错误信息CompletableFutureInteger completableFuture CompletableFuture.supplyAsync(() - {System.out.println(Thread.currentThread().getName() supplyAsyncInteger);//int i 10 / 0;return 1024;});//whenComplete: 参数BiConsumerT, U// 有两个参数一个是T 一个是UT是代表的 正常返回的结果U是代表的 抛出异常的错误信息System.out.println(completableFuture.whenComplete((t, u) - {System.out.println(t t);// 正常的返回结果System.out.println(u u);// 错误信息}).exceptionally((e) - {System.out.println(e.getMessage());return 233;// 可以获取到错误的返回结果}).get());//如果发生了异常get可以获取到exceptionally返回的值} }JMM 理解 对 volatile 的理解 1、保证可见性 import java.util.concurrent.*;public class test {// 如果不加volatile 程序会死循环// 加了volatile是可以保证可见性的private volatile static Integer number 0;//main线程public static void main(String[] args) {//子线程1new Thread(()-{while (number0){}}).start();try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}//子线程2new Thread(()-{while (number0){}}).start();try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}number1;System.out.println(number);} }2、不保证原子性 public class test {private static volatile int number 0;public static void add() {number;// 不是一个原子性操作是 2~3 个操作}public static void main(String[] args) {//理论上number 20000for (int i 1; i 20; i) {new Thread(() - {for (int j 1; j 1000; j) {add();}}).start();}//main gcwhile (Thread.activeCount() 2) {Thread.yield(); //yield让出计算资源并重新竞争资源}System.out.println(Thread.currentThread().getName() ,num number);//每次都不一样} }javap -c test.class反编译字节码文件 import java.util.concurrent.atomic.AtomicInteger;public class test {// 这些类的底层都直接和操作系统挂钩是在内存中修改值。private static volatile AtomicInteger number new AtomicInteger();public static void add(){//number;number.incrementAndGet(); //底层是 CAS 保证的原子性}public static void main(String[] args) {//理论上number20000for (int i 1; i 20; i) {new Thread(()-{for (int j 1; j 1000 ; j) {add();}}).start();}//main gcwhile (Thread.activeCount()2){Thread.yield();}System.out.println(Thread.currentThread().getName(),numnumber);} }3、禁止指令重排 源代码 – 编译器优化重排 – 指令并行也可能会重排 – 内存系统也会重排 – 执行 int x1; //1 int y2; //2 xx5; //3 yx*x; //4//期望的执行顺序是 1_2_3_4 可能执行的顺序会变成2134 1324volatile 可以避免指令重排volatile 中会加一道内存的屏障这个内存屏障可以保证在这个屏障中的指令顺序。 对 JMM 的理解 JMMJava内存模型不存在的东西是一个概念也是一个约定。 关于 JMM 的一些同步的约定 1、线程解锁前必须把共享变量立刻刷回主存2、线程加锁前必须读取主存中的最新值到工作内存中3、加锁和解锁是同一把锁 线程中分为工作内存、主内存。 8种操作读read加载load使用use赋值assign写write存储store加锁lock解锁unlock 内存交互操作有8种虚拟机实现必须保证每一个操作都是原子的不可在分的对于 double 和 long 类型的变量来说load、store、read 和 write 操作在某些平台上允许例外 read读取作用于主内存变量它把一个变量的值从主内存传输到线程的工作内存中以便随后的load动作使用load载入作用于工作内存的变量它把read操作从主存中变量放入工作内存中use使用作用于工作内存中的变量它把工作内存中的变量传输给执行引擎每当虚拟机遇到一个需要使用到变量的值就会使用到这个指令assign赋值作用于工作内存中的变量它把一个从执行引擎中接受到的值放入工作内存的变量副本中store存储作用于主内存中的变量它把一个从工作内存中一个变量的值传送到主内存中以便后续的write使用write写入作用于主内存中的变量它把store操作从工作内存中得到的变量的值放入主内存的变量中lock锁定作用于主内存的变量把一个变量标识为线程独占状态unlock解锁作用于主内存的变量它把一个处于锁定状态的变量释放出来释放后的变量才可以被其他线程锁定 JMM对这八种指令的使用制定了如下规则 不允许 read 和 load、store 和 write 操作之一单独出现必须成对使用。即使用了 read 必须 load使用了store 必须 write不允许线程丢弃他最近的 assign 操作即工作变量的数据改变了之后必须告知主存不允许一个线程将没有 assign 的数据从工作内存同步回主内存 一个新的变量必须在主内存中诞生不允许工作内存直接使用一个未被初始化的变量。就是怼变量实施 use、store操作之前必须经过 assign 和 load 操作一个变量同一时间只有一个线程能对其进行 lock。多次 lock 后必须执行相同次数的 unlock 才能解锁如果对一个变量进行 lock 操作会清空所有工作内存中此变量的值在执行引擎使用这个变量前必须重新 load 或 assign 操作初始化变量的值如果一个变量没有被 lock就不能对其进行 unlock 操作。也不能unlock一个被其他线程锁住的变量对一个变量进行 unlock 操作之前必须把此变量同步回主内存 详解单例模式 饿汉式 //饿汉式单例 public class Hungry {//一上来就实例化可能会浪费空间private byte[] data1 new byte[1024*1024];private byte[] data2 new byte[1024*1024];private byte[] data3 new byte[1024*1024];private byte[] data4 new byte[1024*1024];//私有化构造器private Hungry() {}private final static Hungry HUNGRY new Hungry();public Hungry getInstance() {return HUNGRY;} }懒汉式 // 懒汉式单例 public class LazyMan {//构造器私有化private LazyMan() {System.out.println(Thread.currentThread().getName()OK);}private static LazyMan lazyMan;public static LazyMan getInstance() {if (lazyMan null) {lazyMan new LazyMan();}return lazyMan;}//多线程并会有隐患public static void main(String[] args) {for (int i 0; i 10; i) {new Thread(()-{lazyMan.getInstance();}).start();}} }DCL懒汉式双重检测锁模式的懒汉式单例 // 懒汉式 DCL单例 public class LazyMan {// 构造器私有化private LazyMan() {System.out.println(Thread.currentThread().getName() OK);}// 加volatile防止指令重排private volatile static LazyMan lazyMan;// 双重检测锁模式的 懒汉式单例 DCL懒汉式public static LazyMan getInstance() {// 第一次检查if (lazyMan null) {synchronized (LazyMan.class) {// 第二次检查if (lazyMan null) {lazyMan new LazyMan();/*** 1. 分配内存空间* 2、执行构造方法初始化对象* 3、把这个对象指向这个空间* 执行顺序123,132都有可能* A123 B132* B把这个对象指向这个空间发现不为空执行return* 但是此时在线程A中lazyMan还没有完成构造lazyMan要加volatile防止指令重排*/}}}return lazyMan;}//多线程并发public static void main(String[] args) {for (int i 0; i 10; i) {new Thread(() - {lazyMan.getInstance();}).start();}} }静态内部类实现单例 public class Singleton {private static class SingletonHolder {private static final Singleton INSTANCE new Singleton();}private Singleton() {}public static Singleton getInstance() {return SingletonHolder.INSTANCE;} }通过反射破坏单例修改后的DCL饿汉式 // 懒汉式单例 public class LazyMan {private volatile static LazyMan lazyMan;//私有化构造器private LazyMan() {synchronized (LazyMan.class) {if (lazyMan ! null) {throw new RuntimeException(不要试图使用反射破坏异常);}}System.out.println(Thread.currentThread().getName() OK);}// 双重检测锁模式的 懒汉式单例 DCL懒汉式public static LazyMan getInstance() {if (lazyMan null) {synchronized (LazyMan.class) {if (lazyMan null) {lazyMan new LazyMan();// 不是一个原子性操作}}}return lazyMan;}//多线程并发public static void main(String[] args) throws Exception {LazyMan instance LazyMan.getInstance();ConstructorLazyMan declaredConstructor LazyMan.class.getDeclaredConstructor(null);declaredConstructor.setAccessible(true);//无视私有LazyMan instance2 declaredConstructor.newInstance();System.out.println(instance);System.out.println(instance2);} } //可以继续破坏枚举实现单例防止反射破坏 import java.lang.reflect.Constructor;// enum 本身也是一个 Class 类 public enum EnumSingle {INSTANCE;public EnumSingle getInstance(){return INSTANCE;} }class Test{public static void main(String[] args) throws Exception {EnumSingle instance1 EnumSingle.INSTANCE;//java.lang.NoSuchMethodException: com.zzy.single.EnumSingle.init() 没有空参构造方法//ConstructorEnumSingle declaredConstructor EnumSingle.class.getDeclaredConstructor(null);//反编译中只有有参构造方法 EnumSingle(String s, int i) //java.lang.IllegalArgumentException: Cannot reflectively create enum objectsConstructorEnumSingle declaredConstructor EnumSingle.class.getDeclaredConstructor(String.class,int.class);declaredConstructor.setAccessible(true);EnumSingle instance2 declaredConstructor.newInstance();System.out.println(instance1);System.out.println(instance2);} }理解 CAScompareAndSwap CAS : compareAndSet 比较并交换 import java.util.concurrent.atomic.AtomicInteger;public class test {//CAS : compareAndSet 比较并交换public static void main(String[] args) {AtomicInteger atomicInteger new AtomicInteger(2020);//boolean compareAndSet(int expect, int update)//期望值、更新值//如果实际值 和 期望值相同那么就更新//如果实际值 和 期望值不同那么就不更新System.out.println(atomicInteger.compareAndSet(2020, 2021));System.out.println(atomicInteger.get());//因为期望值是2020 实际值却变成了2021 所以会修改失败//CAS 是CPU的并发原语atomicInteger.getAndIncrement(); //操作System.out.println(atomicInteger.compareAndSet(2020, 2021));System.out.println(atomicInteger.get());} }CAS : compareAndSet 比较并交换源码 public class AtomicInteger extends Number implements java.io.Serializable {private static final long serialVersionUID 6214790243416807050L;// Java无法操作内存C可以Java通过native方法调用C// Java通过Unsafe类操作内存 private static final Unsafe unsafe Unsafe.getUnsafe();private static final long valueOffset;static {try {// 获取内存地址的偏移值valueOffset unsafe.objectFieldOffset(AtomicInteger.class.getDeclaredField(value));} catch (Exception ex) { throw new Error(ex); }}private volatile int value;...public final boolean compareAndSet(int expect, int update) {return unsafe.compareAndSwapInt(this, valueOffset, expect, update);}public final int getAndIncrement() {return unsafe.getAndAddInt(this, valueOffset, 1);} // 内存操作效率很高 // 自旋锁 // Unsafe类 unsafe.getAndAddInt(this, valueOffset, 1) // var1 this; var2 valueOffset; var4 1public final int getAndAddInt(Object var1, long var2, int var4) {int var5;do {// 获取内存地址valueOffset中的值 var5 this.getIntVolatile(var1, var2);} while(!this.compareAndSwapInt(var1, var2, var5, var5 var4));// while中如果当前对象var1中的内存地址偏移值var2这个值如果还等于var5那么这个值等于var5var4return var5;}CAS 出现的 ABA 问题 CAS比较当前工作内存中的值和主内存中的值如果这个值是期望的那么则执行操作如果不是就一直循环使用的是自旋锁。 缺点 循环会耗时一次性只能保证一个共享变量的原子性存在ABA问题 理解 ABA 问题 狸猫换太子 线程1期望值是1要变成2线程2两个操作 1、期望值是1变成3 2、期望是3变成1 所以对于线程1来说A的值还是1所以就出现了问题骗过了线程1 import java.util.concurrent.atomic.AtomicInteger;public class test {// CAS compareAndSet : 比较并交换public static void main(String[] args) {AtomicInteger atomicInteger new AtomicInteger(2020);//public final boolean compareAndSet(int expect, int update)// 如果我期望的值达到了那么就更新否则就不更新, CAS 是CPU的并发原语// 捣乱的线程 System.out.println(atomicInteger.compareAndSet(2020, 2021));System.out.println(atomicInteger.get());System.out.println(atomicInteger.compareAndSet(2021, 2020));System.out.println(atomicInteger.get());// 期望的线程 System.out.println(atomicInteger.compareAndSet(2020, 77777));System.out.println(atomicInteger.get());} }解决 ABA 问题带版本号的原子操作、乐观锁思想 解决 ABA 问题引入原子引用对应的思想乐观锁。 思想带版本号的原子操作 import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicStampedReference;public class test {//AtomicStampedReference 注意如果泛型是一个包装类注意对象的引用问题正常在业务操作这里面比较的都是一个个对象static AtomicStampedReferenceInteger atomicStampedReference newAtomicStampedReference(1, 1);// CAS compareAndSet : 比较并交换public static void main(String[] args) {new Thread(() - {// 获得版本号int stamp atomicStampedReference.getStamp();System.out.println(a1版本号 stamp);try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}// 修改操作时版本号更新 1atomicStampedReference.compareAndSet(1, 2,atomicStampedReference.getStamp(),atomicStampedReference.getStamp() 1);System.out.println(a2版本号 atomicStampedReference.getStamp());// 重新把值改回去 版本号更新 1System.out.println(atomicStampedReference.compareAndSet(2, 1,atomicStampedReference.getStamp(),atomicStampedReference.getStamp() 1));System.out.println(a3版本号 atomicStampedReference.getStamp());}, a).start();// 乐观锁的原理相同new Thread(() - {// 获得版本号int stamp atomicStampedReference.getStamp();System.out.println(b1 stamp);try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(atomicStampedReference.compareAndSet(1, 3,stamp, stamp 1));System.out.println(b2 atomicStampedReference.getStamp());}, b).start();} }公平锁非公平锁 公平锁 非常公平 不能够插队必须先来后到非公平锁非常不公平可以插队 默认都是非公平 // ReentrantLock 源码 public class ReentrantLock implements Lock, java.io.Serializable {...public ReentrantLock() {sync new NonfairSync();}public ReentrantLock(boolean fair) {sync fair ? new FairSync() : new NonfairSync();}... }可重入锁递归锁 拿到外面的锁之后就可以自动获得拿到里面的锁 //Synchronized public class test {public static void main(String[] args) {Phone phone new Phone();new Thread(() - {phone.sms();}, A).start();new Thread(() - {phone.sms();}, B).start();} }class Phone {//外面一把锁public synchronized void sms() {System.out.println(Thread.currentThread().getName() sms);//里面一把锁call();}public synchronized void call() {System.out.println(Thread.currentThread().getName() call);} } //一定是 /* Asms Acall Bsms Bcall */Lock 锁必须配对相当于 lock 和 unlock 必须数量相同在外面加的锁也可以在里面解锁在里面加的锁在外面也可以解锁 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;//Lock public class test {public static void main(String[] args) {Phone2 phone new Phone2();new Thread(() - {phone.sms();}, A).start();new Thread(() - {phone.sms();}, B).start();} }class Phone2 {Lock lock new ReentrantLock();public void sms() {lock.lock();try {System.out.println(Thread.currentThread().getName() sms);//里面还有锁call();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}public void call() {lock.lock();try {System.out.println(Thread.currentThread().getName() call);} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}} }自旋锁 import java.util.concurrent.atomic.AtomicReference;//自旋锁 public class SpinlockDemo {//初始 int - 0; 引用类型 Thread - nullAtomicReferenceThread atomicReference new AtomicReference();// 加锁public void myLock() {Thread thread Thread.currentThread();System.out.println(Thread.currentThread().getName() myLock);//自旋锁while (!atomicReference.compareAndSet(null, thread)) {}}// 解锁public void myUnlock() {Thread thread Thread.currentThread();System.out.println(Thread.currentThread().getName() myUnlock);//自旋锁atomicReference.compareAndSet(thread, null);} }import java.util.concurrent.TimeUnit;public class TestSpinLock {public static void main(String[] args) {//ReentrantLock /* ReentrantLock reentrantLock new ReentrantLock();reentrantLock.lock();reentrantLock.unlock();*/// 底层使用的自旋锁 CASSpinlockDemo lock new SpinlockDemo();new Thread(()-{lock.myLock();try {TimeUnit.SECONDS.sleep(3);} catch (Exception e) {e.printStackTrace();} finally {lock.myUnlock();}},T1).start();new Thread(()-{lock.myLock();try {TimeUnit.SECONDS.sleep(1);} catch (Exception e) {e.printStackTrace();} finally {lock.myUnlock();}},T2).start();} } /* T1 myLock T2 myLock //必须等T1解锁自旋 T1 myUnlock T2 myUnlock */排除死锁 A、B各持有锁试图获取对方的锁例如 import java.util.concurrent.TimeUnit;public class test {public static void main(String[] args) {String lockA lockA;String lockB lockB;new Thread(new MyThread(lockA, lockB), T1).start();new Thread(new MyThread(lockB, lockA), T2).start();} }class MyThread implements Runnable {private String lockA;private String lockB;public MyThread(String lockA, String lockB) {this.lockA lockA;this.lockB lockB;}Overridepublic void run() {synchronized (lockA) {System.out.println(Thread.currentThread().getName() lock: lockA get: lockB);try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lockB) {System.out.println(Thread.currentThread().getName() lock: lockB get: lockA);}}} }使用 jstack 进程号找到死锁问题进程号由 jps -l 得到 ... T2:at JUC_learn.MyThread.run(test.java:36)- waiting to lock 0x053bedc8 (a java.lang.String)- locked 0x053bedf0 (a java.lang.String)at java.lang.Thread.run(Thread.java:745) T1:at JUC_learn.MyThread.run(test.java:36)- waiting to lock 0x053bedf0 (a java.lang.String)- locked 0x053bedc8 (a java.lang.String)at java.lang.Thread.run(Thread.java:745)Found 1 deadlock.
http://www.dnsts.com.cn/news/152630.html

相关文章:

  • 做数学网站重庆社区官网
  • 蒙自网站建设如何免费自己建网站
  • 免费商城网站建站系统福州外贸建站
  • 同城分类信息网站建设王也图片
  • 西城网站建设精美的网页
  • 网站开发技术指标网站还没有做解析是什么意思
  • 浦口区建设中学网站河北网站建设方案详细
  • 上海手机网站开发wordpress插件合集
  • 上海网站建设q479185700棒linux wordpress是什么意思
  • 哈尔滨专业网站营销徐州地产开发公司排名
  • dedecms网站后台模板修改wordpress建站费用
  • 茂名 网站建设创建一个网站要钱吗
  • 移动端企业网站建立网站 要怎么做
  • 新手搭建论坛己做网站建设通官方网站下载
  • 网站修改标题网站做二级域名干什么用
  • 做目的旅游网站的如何用模板搭建网站
  • 大连模板做网站网站建设与管理中专专业
  • 杭州网站设计推荐柚米北仑网站建设
  • 成都公司网站seo买公司 网站建设
  • 网站开发的职位要求国内开源网站
  • 互动营销网站网站运营需要什么行业技术
  • 网站版面做得好的wordpress 首页设置
  • 做网站的公司名称河北住房建设厅网站
  • .net做网站安全吗怎样建设和维护网站
  • 深圳品牌网站设计公司江西省水利水电建设集团招标网站
  • wordpress slider pro天津网络优化网站建设
  • 网站广告用ps如何做泉州自助建站软件
  • 怎么在网站上添加广告代码西宁建设网站的公司
  • 网站开发技术试验总结网站建设网站合同版本
  • wordpress 印象码西安seo外包工作室