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

做产品推广的网站有哪些app使用什么做的网站

做产品推广的网站有哪些,app使用什么做的网站,亚马逊店铺怎么注册流程,做网站第一步要学什么1.公平锁 / 非公平锁2.可重入锁 / 不可重入锁3.独享锁 / 共享锁4.互斥锁 / 读写锁5.乐观锁 / 悲观锁6.分段锁7.偏向锁 / 轻量级锁 / 重量级锁8.自旋锁一、公平锁 / 非公平锁公平锁公平锁是指多个线程按照申请锁的顺序来获取锁。非公平锁非公平锁是指多个线程获取锁的顺序并不是…1.公平锁 / 非公平锁2.可重入锁 / 不可重入锁3.独享锁 / 共享锁4.互斥锁 / 读写锁5.乐观锁 / 悲观锁6.分段锁7.偏向锁 / 轻量级锁 / 重量级锁8.自旋锁一、公平锁 / 非公平锁公平锁公平锁是指多个线程按照申请锁的顺序来获取锁。非公平锁非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序有可能后申请的线程比先申请的线程优先获取锁。有可能会造成优先级反转或者饥饿现象。对于Java ReentrantLock而言通过构造函数指定该锁是否是公平锁默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。对于Synchronized而言也是一种非公平锁。由于其并不像ReentrantLock是通过AQS的来实现线程调度所以并没有任何办法使其变成公平锁。二、可重入锁 / 不可重入锁可重入锁广义上的可重入锁指的是可重复可递归调用的锁在外层使用锁之后在内层仍然可以使用并且不发生死锁(前提得是同一个对象或者class)这样的锁就叫做可重入锁。ReentrantLock和synchronized都是可重入锁synchronized void setA() throws Exception{Thread.sleep(1000);setB();}synchronized void setB() throws Exception{Thread.sleep(1000);}上面的代码就是一个可重入锁的一个特点如果不是可重入锁的话setB可能不会被当前线程执行可能造成死锁。不可重入锁不可重入锁与可重入锁相反不可递归调用递归调用就发生死锁。看到一个经典的讲解使用自旋锁来模拟一个不可重入锁代码如下import java.util.concurrent.atomic.AtomicReference;public class UnreentrantLock {private AtomicReference owner new AtomicReference();public void lock() {Thread current Thread.currentThread();//这句是很经典的“自旋”语法AtomicInteger中也有 for (;;) {if (!owner.compareAndSet(null, current)) {return;}}}public void unlock() {Thread current Thread.currentThread();owner.compareAndSet(current, null);}}代码也比较简单使用原子引用来存放线程同一线程两次调用lock()方法如果不执行unlock()释放锁的话第二次调用自旋的时候就会产生死锁这个锁就不是可重入的而实际上同一个线程不必每次都去释放锁再来获取锁这样的调度切换是很耗资源的。把它变成一个可重入锁import java.util.concurrent.atomic.AtomicReference;public class UnreentrantLock {private AtomicReference owner new AtomicReference();private int state 0;public void lock() {Thread current Thread.currentThread();if (current owner.get()) {state;return;}//这句是很经典的“自旋”式语法AtomicInteger中也有 for (;;) {if (!owner.compareAndSet(null, current)) {return;}}}public void unlock() {Thread current Thread.currentThread();if (current owner.get()) {if (state ! 0) {state--;} else {owner.compareAndSet(current, null);}}}}在执行每次操作之前判断当前锁持有者是否是当前对象采用state计数不用每次去释放锁。ReentrantLock中可重入锁实现这里看非公平锁的锁获取方法final boolean nonfairTryAcquire(int acquires) {final Thread current Thread.currentThread();int c getState();if (c 0) {if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}//就是这里 else if (current getExclusiveOwnerThread()) {int nextc c acquires;if (nextc 0) // overflow throw new Error(Maximum lock count exceeded);setState(nextc);return true;}return false;}在AQS中维护了一个private volatile int state来计数重入次数避免了频繁的持有释放操作这样既提升了效率又避免了死锁。三、独享锁 / 共享锁独享锁和共享锁在你去读C.U.T包下的ReeReentrantLock和ReentrantReadWriteLock你就会发现它俩一个是独享一个是共享锁。独享锁该锁每一次只能被一个线程所持有。共享锁该锁可被多个线程共有典型的就是ReentrantReadWriteLock里的读锁它的读锁是可以被共享的但是它的写锁确每次只能被独占。另外读锁的共享可保证并发读是非常高效的但是读写和写写写读都是互斥的。独享锁与共享锁也是通过AQS来实现的通过实现不同的方法来实现独享或者共享对于Synchronized而言当然是独享锁。四、互斥锁 / 读写锁互斥锁在访问共享资源之前对进行加锁操作在访问完成之后进行解锁操作。 加锁后任何其他试图再次加锁的线程会被阻塞直到当前进程解锁。如果解锁时有一个以上的线程阻塞那么所有该锁上的线程都被编程就绪状态 第一个变为就绪状态的线程又执行加锁操作那么其他的线程又会进入等待。 在这种方式下只有一个线程能够访问被互斥锁保护的资源读写锁读写锁既是互斥锁又是共享锁read模式是共享write是互斥(排它锁)的。读写锁有三种状态读加锁状态、写加锁状态和不加锁状态读写锁在Java中的具体实现就是ReadWriteLock一次只有一个线程可以占有写模式的读写锁但是多个线程可以同时占有读模式的读写锁。只有一个线程可以占有写状态的锁但可以有多个线程同时占有读状态锁这也是它可以实现高并发的原因。当其处于写状态锁下任何想要尝试获得锁的线程都会被阻塞直到写状态锁被释放如果是处于读状态锁下允许其它线程获得它的读状态锁但是不允许获得它的写状态锁直到所有线程的读状态锁被释放为了避免想要尝试写操作的线程一直得不到写状态锁当读写锁感知到有线程想要获得写状态锁时便会阻塞其后所有想要获得读状态锁的线程。所以读写锁非常适合资源的读操作远多于写操作的情况。五、乐观锁 / 悲观锁悲观锁总是假设最坏的情况每次去拿数据的时候都认为别人会修改所以每次在拿数据的时候都会上锁这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用其它线程阻塞用完后再把资源转让给其它线程)。传统的关系型数据库里边就用到了很多这种锁机制比如行锁表锁等读锁写锁等都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。乐观锁总是假设最好的情况每次去拿数据的时候都认为别人不会修改所以不会上锁但是在更新的时候会判断一下在此期间别人有没有去更新这个数据可以使用版本号机制和CAS算法实现。乐观锁适用于多读的应用类型这样可以提高吞吐量像数据库提供的类似于write_condition机制其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS实现的。六、分段锁分段锁其实是一种锁的设计并不是具体的一种锁对于ConcurrentHashMap而言其并发的实现就是通过分段锁的形式来实现高效的并发操作。并发容器类的加锁机制是基于粒度更小的分段锁分段锁也是提升多并发程序性能的重要手段之一。在并发程序中串行操作是会降低可伸缩性并且上下文切换也会减低性能。在锁上发生竞争时将通水导致这两种问题使用独占锁时保护受限资源的时候基本上是采用串行方式—-每次只能有一个线程能访问它。所以对于可伸缩性来说最大的威胁就是独占锁。我们一般有三种方式降低锁的竞争程度1、减少锁的持有时间2、降低锁的请求频率3、使用带有协调机制的独占锁这些机制允许更高的并发性。在某些情况下我们可以将锁分解技术进一步扩展为一组独立对象上的锁进行分解这成为分段锁。其实说的简单一点就是容器里有多把锁每一把锁用于锁容器其中一部分数据那么当多线程访问容器里不同数据段的数据时线程间就不会存在锁竞争从而可以有效的提高并发访问效率这就是ConcurrentHashMap所使用的锁分段技术首先将数据分成一段一段的存储然后给每一段数据配一把锁当一个线程占用锁访问其中一个段数据的时候其他段的数据也能被其他线程访问。比如在ConcurrentHashMap中使用了一个包含16个锁的数组每个锁保护所有散列桶的1/16其中第N个散列桶由第(N mod 16)个锁来保护。假设使用合理的散列算法使关键字能够均匀的分部那么这大约能使对锁的请求减少到越来的1/16。也正是这项技术使得ConcurrentHashMap支持多达16个并发的写入线程。七、偏向锁 / 轻量级锁 / 重量级锁锁的状态1.无锁状态2.偏向锁状态3.轻量级锁状态4.重量级锁状态锁的状态是通过对象监视器在对象头中的字段来表明的。四种状态会随着竞争的情况逐渐升级而且是不可逆的过程即不可降级。这四种状态都不是Java语言中的锁而是Jvm为了提高锁的获取与释放效率而做的优化(使用synchronized时)。偏向锁偏向锁是指一段同步代码一直被一个线程所访问那么该线程会自动获取锁。降低获取锁的代价。轻量级轻量级锁是指当锁是偏向锁的时候被另一个线程所访问偏向锁就会升级为轻量级锁其他线程会通过自旋的形式尝试获取锁不会阻塞提高性能。重量级锁重量级锁是指当锁为轻量级锁的时候另一个线程虽然是自旋但自旋不会一直持续下去当自旋一定次数的时候还没有获取到锁就会进入阻塞该锁膨胀为重量级锁。重量级锁会让其他申请的线程进入阻塞性能降低。八、自旋锁我们知道CAS算法是乐观锁的一种实现方式CAS算法中又涉及到自旋锁所以这里给大家讲一下什么是自旋锁。简单回顾一下CAS算法CAS是英文单词Compare and Swap(比较并交换)是一种有名的无锁算法。无锁编程即不使用锁的情况下实现多线程之间的变量同步也就是在没有线程被阻塞的情况下实现变量的同步所以也叫非阻塞同步(Non-blocking Synchronization)。CAS算法涉及到三个操作数1.需要读写的内存值 V2.进行比较的值 A3.拟写入的新值 B更新一个变量的时候只有当变量的预期值A和内存地址V当中的实际值相同时才会将内存地址V对应的值修改为B否则不会执行任何操作。一般情况下是一个自旋操作即不断的重试。什么是自旋锁自旋锁(spinlock)是指当一个线程在获取锁的时候如果锁已经被其它线程获取那么该线程将循环等待然后不断的判断锁是否能够被成功获取直到获取到锁才会退出循环。它是为实现保护共享资源而提出一种锁机制。其实自旋锁与互斥锁比较类似它们都是为了解决对某项资源的互斥使用。无论是互斥锁还是自旋锁在任何时刻最多只能有一个保持者也就说在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁如果资源已经被占用资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠如果自旋锁已经被别的执行单元保持调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁”自旋”一词就是因此而得名。Java如何实现自旋锁下面是个简单的例子public class SpinLock {private AtomicReference cas new AtomicReference();public void lock() {Thread current Thread.currentThread();// 利用CAS while (!cas.compareAndSet(null, current)) {// DO nothing }}public void unlock() {Thread current Thread.currentThread();cas.compareAndSet(current, null);}}lock()方法利用的CAS当第一个线程A获取锁的时候能够成功获取到不会进入while循环如果此时线程A没有释放锁另一个线程B又来获取锁此时由于不满足CAS所以就会进入while循环不断判断是否满足CAS直到A线程调用unlock方法释放了该锁。自旋锁存在的问题1、如果某个线程持有锁的时间过长就会导致其它等待获取锁的线程进入循环等待消耗CPU。使用不当会造成CPU使用率极高。2、上面Java实现的自旋锁不是公平的即无法满足等待时间最长的线程优先获取锁。不公平的锁就会存在“线程饥饿”问题。自旋锁的优点1、自旋锁不会使线程状态发生切换一直处于用户态即线程一直都是active的不会使线程进入阻塞状态减少了不必要的上下文切换执行速度快2、非自旋锁在获取不到锁的时候会进入阻塞状态从而进入内核态当获取到锁的时候需要从内核态恢复需要线程上下文切换。 (线程被阻塞后便进入内核(Linux)调度状态这个会导致系统在用户态与内核态之间来回切换严重影响锁的性能)可重入的自旋锁和不可重入的自旋锁文章开始的时候的那段代码仔细分析一下就可以看出它是不支持重入的即当一个线程第一次已经获取到了该锁在锁释放之前又一次重新获取该锁第二次就不能成功获取到。由于不满足CAS所以第二次获取会进入while循环等待而如果是可重入锁第二次也是应该能够成功获取到的。而且即使第二次能够成功获取那么当第一次释放锁的时候第二次获取到的锁也会被释放而这是不合理的。为了实现可重入锁我们需要引入一个计数器用来记录获取锁的线程数。public class ReentrantSpinLock {private AtomicReference cas new AtomicReference();private int count;public void lock() {Thread current Thread.currentThread();if (current cas.get()) { // 如果当前线程已经获取到了锁线程数增加一然后返回 count;return;}// 如果没获取到锁则通过CAS自旋 while (!cas.compareAndSet(null, current)) {// DO nothing }}public void unlock() {Thread cur Thread.currentThread();if (cur cas.get()) {if (count 0) {// 如果大于0表示当前线程多次获取了该锁释放锁通过count减一来模拟 count--;} else {// 如果count0可以将锁释放这样就能保证获取锁的次数与释放锁的次数是一致的了。 cas.compareAndSet(cur, null);}}}}自旋锁与互斥锁1.自旋锁与互斥锁都是为了实现保护资源共享的机制。2.无论是自旋锁还是互斥锁在任意时刻都最多只能有一个保持者。3获取互斥锁的线程如果锁已经被占用则该线程将进入睡眠状态获取自旋锁的线程则不会睡眠而是一直循环等待锁释放。自旋锁总结1.自旋锁线程获取锁的时候如果锁被其他线程持有则当前线程将循环等待直到获取到锁。2.自旋锁等待期间线程的状态不会改变线程一直是用户态并且是活动的(active)。3.自旋锁如果持有锁的时间太长则会导致其它等待获取锁的线程耗尽CPU。4.自旋锁本身无法保证公平性同时也无法保证可重入性。5.基于自旋锁可以实现具备公平性和可重入性质的锁。
http://www.zqtcl.cn/news/987345/

相关文章:

  • 好的ftp网站微信小程序开发基础
  • 西安 网站 公司wordpress+帖子置顶
  • 广州开发网站服务上海千途网站建设
  • 网站建设功能分为几种百度搜索数据
  • 电影网站模板html微信开发者代码管理
  • 小程序ui界面设计手机优化大师官网
  • 佳木斯市建设局网站网络游戏名
  • 建筑钢结构网站汉阳网站建设哪家便宜
  • 营销型网站建设评价临湘网站建设
  • 做网站的价格参考巴中建网站的公司
  • 张家口建设网站网络技术工程师
  • 大型网站后台登录地址一般是如何设置的哪里网站用vue.js做的
  • 网页设计规范图标设计百度seo优化多少钱
  • 网站打开速度概念建筑网站知乎
  • 网站的flash怎么做的杭州市城乡建设网官网
  • 宿迁网站建设排名wordpress多站点可视化
  • 苏州好的做网站的公司哪家好前端如何做响应式网站
  • 广州网站建设招标推广方式有哪些渠道
  • 郑州做网站狼牙东莞建设造价信息网站
  • 网站制作代理加盟国内seo服务商
  • 如何在建设银行网站预约纪念币网络销售好不好做
  • 利用淘宝视频服务做视频网站聊城做网站价格
  • 做美容行业的网站哪个好广西互联网企业
  • 做网站平台的营业执照江镇做包子网站
  • 网站建设 摄影服务wordpress破解模板
  • 网站规划中的三种常用类型宁波海曙区建设局网站
  • dede做网站湖北网址大全
  • 如何注册网站的名字html表单制作
  • 中国建设工程协会标准网站什么网站做推广比较好
  • 长沙专业网站建设怎么做关于网站建设的投标书