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

pc 手机网站建设电子商务网站的推广方法

pc 手机网站建设,电子商务网站的推广方法,广东人才网,付费网站怎么做文章目录前言一、synchronized的特性1.1 原子性1.2 可见性1.3 有序性1.4 可重入性二、synchronized的用法三、synchronized锁的实现3.1 同步方法3.2 同步代码块四、synchronized锁的底层实现五、JVM对synchronized的优化5.1 锁膨胀5.1.1 偏向锁5.1.2 轻量级锁5.1.3 重量级锁5.2… 文章目录前言一、synchronized的特性1.1 原子性1.2 可见性1.3 有序性1.4 可重入性二、synchronized的用法三、synchronized锁的实现3.1 同步方法3.2 同步代码块四、synchronized锁的底层实现五、JVM对synchronized的优化5.1 锁膨胀5.1.1 偏向锁5.1.2 轻量级锁5.1.3 重量级锁5.2 锁消除5.3 锁粗化5.4 自旋锁与自适应自旋锁结语前言 如果某一个资源被多个线程共享为了避免因为资源抢占导致资源数据错乱我们需要对线程进行同步那么synchronized就是实现线程同步的关键字可以说在并发控制中是必不可少的部分今天就来看一下synchronized的使用和底层原理。 一、synchronized的特性 1.1 原子性 所谓原子性就是指一个操作或者多个操作要么全部执行并且执行的过程不会被任何因素打断要么就都不执行。 在Java中对基本数据类型的变量的读取和赋值操作是原子性操作即这些操作是不可被中断的要么执行要么不执行。但是像i、i1等操作字符就不是原子性的它们是分成读取、计算、赋值几步操作原值在这些步骤还没完成时就可能已经被赋值了那么最后赋值写入的数据就是脏数据无法保证原子性。被synchronized修饰的类或对象的所有操作都是原子的因为在执行操作之前必须先获得类或对象的锁直到执行完才能释放这中间的过程无法被中断除了已经废弃的stop()方法即保证了原子性。 注意经常会比较synchronized和volatile它们俩特性上最大的区别就在于原子性volatile不具备原子性。 1.2 可见性 可见性是指多个线程访问一个资源时该资源的状态、值信息等对于其他线程都是可见的。 synchronized和volatile都具有可见性其中synchronized对一个类或对象加锁时一个线程如果要访问该类或对象必须先获得它的锁而这个锁的状态对于其他任何线程都是可见的并且在释放锁之前会将对变量的修改刷新到主存当中保证资源变量的可见性如果某个线程占用了该锁其他线程就必须在锁池中等待锁的释放。 而volatile的实现类似被volatile修饰的变量每当值需要修改时都会立即更新主存主存是共享的所有线程可见所以确保了其他线程读取到的变量永远是最新值保证可见性。 1.3 有序性 有序性值程序执行的顺序按照代码先后执行。 synchronized和volatile都具有有序性Java允许编译器和处理器对指令进行重排但是指令重排并不会影响单线程的顺序它影响的是多线程并发执行的顺序性。synchronized保证了每个时刻都只有一个线程访问同步代码块也就确定了线程执行同步代码块是分先后顺序的保证了有序性。 1.4 可重入性 synchronized和ReentrantLock都是可重入锁。当一个线程试图操作一个由其他线程持有的对象锁的临界资源时将会处于阻塞状态但当一个线程再次请求自己持有对象锁的临界资源时这种情况属于重入锁。通俗一点讲就是说一个线程拥有了锁仍然还可以重复申请锁。 二、synchronized的用法 synchronized可以修饰静态方法、成员函数同时还可以直接定义代码块但是归根结底它上锁的资源只有两类一个是对象一个是类。 先看看下面的代码初学者看到先不要晕后面慢慢讲解 首先我们知道被static修饰的静态方法、静态属性都是归类所有同时该类的所有实例对象都可以访问。但是普通成员属性、成员方法是归实例化的对象所有必须实例化之后才能访问这也是为什么静态方法不能访问非静态属性的原因。我们明确了这些属性、方法归哪些所有之后就可以理解上面几个synchronized的锁到底是加给谁的了。 首先看第一个synchronized所加的方法是add1()该方法没有被static修饰也就是说该方法是归实例化的对象所有那么这个锁就是加给Test1类所实例化的对象。 然后是add2()方法该方法是静态方法归Test1类所有所以这个锁是加给Test1类的。 最后是method()方法中两个同步代码块第一个代码块所锁定的是Test1.class通过字面意思便知道该锁是加给Test1类的而下面那个锁定的是instance这个instance是Test1类的一个实例化对象自然它所上的锁是给instance实例化对象的。 弄清楚这些锁是上给谁的就应该很容易懂synchronized的使用啦只要记住要进入同步方法或同步块必须先获得相应的锁才行。那么我下面再列举出一个非常容易进入误区的代码看看你是否真的理解了上面的解释。 上面的简单意思就是用两个线程分别对i加100万次理论结果应该是200万而且我还加了synchronized锁住了add方法保证了其线程安全性。可是我无论运行多少次都是小于200万的为什么呢 原因就在于synchronized加锁的函数这个方法是普通成员方法那么锁就是加给对象的但是在创建线程时却new了两个Test2实例也就是说这个锁是给这两个实例加的锁并没有达到同步的效果所以才会出现错误。至于为什么小于200万要理解i的过程就明白了请阅读详谈Java中的CAS操作 三、synchronized锁的实现 synchronized有两种形式上锁一个是对方法上锁一个是构造同步代码块。他们的底层实现其实都一样在进入同步代码之前先获取锁获取到锁之后锁的计数器1同步代码执行完锁的计数器-1如果获取失败就阻塞式等待锁的释放。只是他们在同步块识别方式上有所不一样从class字节码文件可以表现出来一个是通过方法flags标志一个是monitorenter和monitorexit指令操作。 3.1 同步方法 首先来看在方法上上锁我们就新定义一个同步方法然后进行反编译查看其字节码 可以看到在add方法的flags里面多了一个ACC_SYNCHRONIZED标志这标志用来告诉JVM这是一个同步方法在进入该方法之前先获取相应的锁锁的计数器加1方法结束后计数器-1如果获取失败就阻塞住知道该锁被释放。 看不懂字节码指令的朋友可以先阅读下面两篇文章了解一下class的结构 详解Class类文件的结构上详解Class类文件的结构下 3.2 同步代码块 我们新定义一个同步代码块编译出class字节码然后找到method方法所在的指令块可以清楚的看到其实现上锁和释放锁的过程截图如下 从反编译的同步代码块可以看到同步块是由monitorenter指令进入然后monitorexit释放锁在执行monitorenter之前需要尝试获取锁如果这个对象没有被锁定或者当前线程已经拥有了这个对象的锁那么就把锁的计数器加1。当执行monitorexit指令时锁的计数器也会减1。当获取锁失败时会被阻塞一直等待锁被释放。 但是为什么会有两个monitorexit呢其实第二个monitorexit是来处理异常的仔细看反编译的字节码正常情况下第一个monitorexit之后会执行goto指令而该指令转向的就是23行的return也就是说正常情况下只会执行第一个monitorexit释放锁然后返回。而如果在执行中发生了异常第二个monitorexit就起作用了它是由编译器自动生成的在发生异常时处理异常然后释放掉锁。 四、synchronized锁的底层实现 在理解锁实现原理之前先了解一下Java的对象头和Monitor在JVM中对象是分成三部分存在的对象头、实例数据、对其填充。 实例数据和对其填充与synchronized无关这里简单说一下阅读《深入理解Java虚拟机》读者可仔细阅读该书相关章节学习。实例数据存放类的属性数据信息包括父类的属性信息如果是数组的实例部分还包括数组的长度这部分内存按4字节对齐对其填充不是必须部分由于虚拟机要求对象起始地址必须是8字节的整数倍对齐填充仅仅是为了使字节对齐。 对象头是我们需要关注的重点它是synchronized实现锁的基础因为synchronized申请锁、上锁、释放锁都与对象头有关。对象头主要结构是由Mark Word 和 Class Metadata Address 组成其中Mark Word存储对象的hashCode、锁信息或分代年龄或GC标志等信息Class Metadata Address是类型指针指向对象的类元数据JVM通过该指针确定该对象是哪个类的实例。 锁也分不同状态JDK6之前只有两个状态无锁、有锁重量级锁而在JDK6之后对synchronized进行了优化新增了两种状态总共就是四个状态无锁状态、偏向锁、轻量级锁、重量级锁其中无锁就是一种状态了。锁的类型和状态在对象头Mark Word中都有记录在申请锁、锁升级等过程中JVM都需要读取对象的Mark Word数据。 每一个锁都对应一个monitor对象在HotSpot虚拟机中它是由ObjectMonitor实现的C实现。每个对象都存在着一个monitor与之关联对象与其monitor之间的关系有存在多种实现方式如monitor可以与对象一起创建销毁或当线程试图获取对象锁时自动生成但当一个monitor被某个线程持有后它便处于锁定状态。 ObjectMonitor() {_header NULL;_count 0; //锁计数器_waiters 0,_recursions 0;_object NULL;_owner NULL;_WaitSet NULL; //处于wait状态的线程会被加入到_WaitSet_WaitSetLock 0 ;_Responsible NULL ;_succ NULL ;_cxq NULL ;FreeNext NULL ;_EntryList NULL ; //处于等待锁block状态的线程会被加入到该列表_SpinFreq 0 ;_SpinClock 0 ;OwnerIsThread 0 ;}该段摘自https://blog.csdn.net/javazejian/article/details/72828483 ObjectMonitor中有两个队列_WaitSet和_EntryList用来保存ObjectWaiter对象列表(每个等待锁的线程都会被封装ObjectWaiter对象)_owner指向持有ObjectMonitor对象的线程当多个线程同时访问一段同步代码时首先会进入_EntryList 集合当线程获取到对象的monitor 后进入 _Owner 区域并把monitor中的owner变量设置为当前线程同时monitor中的计数器count加1若线程调用 wait() 方法将释放当前持有的monitorowner变量恢复为nullcount自减1同时该线程进入 WaitSe t集合中等待被唤醒。若当前线程执行完毕也将释放monitor(锁)并复位变量的值以便其他线程进入获取monitor(锁)。 monitor对象存在于每个Java对象的对象头中(存储的指针的指向)synchronized锁便是通过这种方式获取锁的也是为什么Java中任意对象可以作为锁的原因同时也是notify/notifyAll/wait等方法存在于顶级对象Object中的原因(关于这点稍后还会进行分析) 五、JVM对synchronized的优化 从最近几个jdk版本中可以看出Java的开发团队一直在对synchronized优化其中最大的一次优化就是在jdk6的时候新增了两个锁状态通过锁消除、锁粗化、自旋锁等方法使用各种场景给synchronized性能带来了很大的提升。 5.1 锁膨胀 上面讲到锁有四种状态并且会因实际情况进行膨胀升级其膨胀方向是无锁——偏向锁——轻量级锁——重量级锁并且膨胀方向不可逆。 5.1.1 偏向锁 一句话总结它的作用减少统一鲜橙获取锁的代价。在大多数情况下锁不存在多线程竞争总是由同一鲜橙多次获得那么此时就是偏向锁。 核心思想 如果一个线程获得了锁那么锁就进入偏向模式此时Mark Word的结构也就变为偏向锁结构当该线程再次请求锁时无需再做任何同步操作即获取锁的过程只需要检查Mark Word的锁标记位为偏向锁以及当前线程ID等于Mark Word的ThreadID即可这样就省去了大量有关锁申请的操作。 5.1.2 轻量级锁 轻量级锁是由偏向锁升级而来当存在第二个线程申请同一个锁对象时偏向锁就会立即升级为轻量级锁。注意这里的第二个线程只是申请锁不存在两个线程同时竞争锁可以是一前一后地交替执行同步块。 5.1.3 重量级锁 重量级锁是由轻量级锁升级而来当同一时间有多个线程竞争锁时锁就会被升级成重量级锁此时其申请锁带来的开销也就变大。 重量级锁一般使用场景会在追求吞吐量同步块或者同步方法执行时间较长的场景。 5.2 锁消除 消除锁是虚拟机另外一种锁的优化这种优化更彻底在JIT编译时对运行上下文进行扫描去除不可能存在竞争的锁。比如下面代码的method1和method2的执行效率是一样的因为object锁是私有变量不存在所得竞争关系。 5.3 锁粗化 锁粗化是虚拟机对另一种极端情况的优化处理通过扩大锁的范围避免反复加锁和释放锁。比如下面method3经过锁粗化优化之后就和method4执行效率一样了。 5.4 自旋锁与自适应自旋锁 轻量级锁失败后虚拟机为了避免线程真实地在操作系统层面挂起还会进行一项称为自旋锁的优化手段。 自旋锁许多情况下共享数据的锁定状态持续时间较短切换线程不值得通过让线程执行循环等待锁的释放不让出CPU。如果得到锁就顺利进入临界区。如果还不能获得锁那就会将线程在操作系统层面挂起这就是自旋锁的优化方式。但是它也存在缺点如果锁被其他线程长时间占用一直不释放CPU会带来许多的性能开销。 自适应自旋锁这种相当于是对上面自旋锁优化方式的进一步优化它的自旋的次数不再固定其自旋的次数由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定这就解决了自旋锁带来的缺点。 结语 synchronized关键字是并发编程不可或缺的部分个人认为能真实理解其内部运作原理能对平时的开发带来很大意义上的帮助希望这篇文章能帮助你
http://www.zqtcl.cn/news/834062/

相关文章:

  • 泰安的网站建设公司哪家好国外ps网站
  • 网站建设制作方案做字典网站开发
  • 安徽道遂建设工程有限公司网站汽车之家网页
  • 仙居网站建设贴吧马鞍山钢铁建设集团有限公司网站
  • 编写网站 语言微网站开发语言
  • 深圳网站建设优化网站建设与维护培训
  • 张家港网站开发wordpress后台登录地址改
  • 郑州做网站的公司哪家好做网站运营工资是不是很低
  • 做网站电销公司开发个网站怎么做
  • 廊坊做网站哪家好深圳快速网站制
  • 网站开发文档实训小结与讨论做网站建设业务员好吗
  • 网站开发知识产权归属好看的个人网站设计
  • 怎么学习企业网站维护江西省城乡建设培训网站官方网站
  • 电脑网站 源码php网站数据库修改
  • 做网站系统的答辩ppt范文商品关键词优化的方法
  • 长沙网站设计公司怎么样如何在网站上推广自己的产品
  • 龙岗网站设计农业网站模板WordPress
  • 摄像头监控设备企业网站模板聊城网站设计公司
  • 做英文网站賺钱建筑设计资料网站
  • 上海专业网站建设平台百度sem认证
  • 个人房产查询系统网站官网推广普通话 奋进新征程
  • 网站设计理念介绍石家庄业之峰装饰公司怎么样
  • 博乐建设工程信息网站ppt软件下载免费版
  • 宿州公司网站建设企业管理培训课程讲座大全
  • 企业网站营销的优缺点Vs做的网站调试时如何适应网页
  • 策划案网站构成怎么写wordpress建个人博客
  • 自己做的网站别人怎么访问美容行业网站建设多少价格
  • 网站建设与运营 教材 崔海口个人建站模板
  • 做本地网站赚钱吗wordpress桌面宠物
  • 滁州市城市建设投资有限公司网站云服务器里面做网站播放器