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

山西省网站建设_网站建设公司_Figma_seo优化

网站运营经验,网站footer内容,公司网页设计文案,做调查问卷赚钱注册网站1. 创建线程的四种方式实现Runnable 重写run方法继承Thread 重写run方法线程池创建 Executors.newCachedThreadPool()实现Callable接口2. Thread线程操作方法当前线程睡眠指定mills毫秒Thread.sleep([mills])当前线程优雅让出执行权Thread.yield()例如Thread t1, t2#xff0c…1. 创建线程的四种方式实现Runnable 重写run方法继承Thread 重写run方法线程池创建 Executors.newCachedThreadPool()实现Callable接口2. Thread线程操作方法当前线程睡眠指定mills毫秒Thread.sleep([mills])当前线程优雅让出执行权Thread.yield()例如Thread t1, t2在t2的run方法中调用t1.join(),线程t2将等待t1完成后执行join3. Thread状态4. synchronized锁住的是对象而不是代码this 等价于 当前类.class锁定方法非锁定方法同时进行锁在执行过程中发生异常会自动释放锁synchronized获得的锁是可重入的锁升级 偏向锁-自旋锁-重量级锁synchronized(object)不能用String常量/IntegerLong等基本数据类型锁定对象的时候要保证对象不能被重写最好加final定义4. volatile保证线程可见性禁止指令重排序volatile并不能保证多个线程修改的一致性要保持一致性还是需要synchronized关键字volatile 引用类型包括数组只能保证引用本身的可见性不能保证内部字段的可见性volatile关 键字只能用于变量而不可以修饰方法以及代码块5. synchronized与AtomicLong以及LongAdder的效率对比Synchronized 是需要加锁的效率偏低AtomicLong 不需要申请锁使用CAS机制LongAdder 使用分段锁所以效率好在并发数量特别高的时候LongAdder最合适6. ConcurrentHashMap的分段锁原理分段锁就是将数据分段上锁把锁进一步细粒度化有助于提升并发效率。HashTable容器在竞争激烈的并发环境下表现出效率低下的原因是所有访问HashTable的线程都必须竞争同一把锁假如容器里有多把锁每一把锁用于锁容器其中一部分数据那么当多线程访问容器里不同数据段的数据时线程间就不会存在锁竞争从而可以有效提高并发访问效率这就是ConcurrentHashMap所使用的锁分段技术。首先将数据分成一段一段地存储然后给每一段数据配一把锁当一个线程占用锁访问其中一个段数据的时候其他段的数据也能被其他线程访问。7. ReentrantLockReentrantLock可以替代synchronized但是ReentrantLock必须手动开启锁/关闭锁synchronized遇到异常会自动释放锁ReentrantLock需要手动关闭一般都是放在finally中关闭定义锁 Lock lock new ReentrantLock();开启 lock.lock();关闭 lock.unlock();使用Reentrantlock可以进行“尝试锁定”tryLock这样无法锁定或者在指定时间内无法锁定线程可以决定是否继续等待。使用tryLock进行尝试锁定不管锁定与否方法都将继续执行可以根据tryLock的返回值来判定是否锁定也可以指定tryLock的时间由于tryLock(time)抛出异常所以要注意unclock的处理必须放到finally中如果tryLock未锁定则不需要unlock使用ReentrantLock还可以调用lockInterruptibly方法可以对线程interrupt方法做出响应在一个线程等待锁的过程中可以被打断new ReentrantLock(true) 表示公平锁不带参数默认为false非公平锁8. CountDownLatchcountDownLatch这个类可以使一个线程等待其他线程各自执行完毕后再执行。是通过一个计数器来实现的计数器的初始值是线程的数量。当调用countDown()方法后每当一个线程执行完毕后计数器的值就-1当计数器的值为0时表示所有线程都执行完毕然后在闭锁上等待的线程就可以恢复工作了。线程中调用countDown()方法开始计数在调用await()方法的线程中当计数器为0是后续才会继续执行否则一直等待也可以使用latch.await(timeout, unit)在等待timeout时间后如果计数器不为0线程仍将继续。countDown()之后的代码不受计数器控制与join区别使用join的线程将被阻塞使用countDown的线程不受影响只有调用await的时候才会阻塞8. CyclicBarrier作用就是会让指定数量的数量由构造函数指定所有线程都等待完成后才会继续下一步行动。构造函数public CyclicBarrier(int parties)public CyclicBarrier(int parties, Runnable barrierAction)parties 是线程的个数barrierAction为最后一个到达线程要做的任务所有线程会等待全部线程到达栅栏之后才会继续执行并且最后到达的线程会完成 Runnable 的任务。实现原理在CyclicBarrier的内部定义了一个Lock对象每当一个线程调用await方法时将拦截的线程数减1然后判断剩余拦截数是否为初始值parties如果不是进入Lock对象的条件队列等待。如果是执行barrierAction对象的Runnable方法然后将锁的条件队列中的所有线程放入锁等待队列中这些线程会依次的获取锁、释放锁。9. Phaser可重复使用的同步屏障功能类似于CyclicBarrier和CountDownLatch但支持更灵活的使用。Phaser使我们能够建立在逻辑线程需要才去执行下一步的障碍等。我们可以协调多个执行阶段为每个程序阶段重用Phaser实例。每个阶段可以有不同数量的线程等待前进到另一个阶段。我们稍后会看一个使用阶段的示例。要参与协调线程需要使用Phaser实例 register() 本身。请注意这只会增加注册方的数量我们无法检查当前线程是否已注册 - 我们必须将实现子类化以支持此操作。线程通过调用 arriAndAwaitAdvance() 来阻止它到达屏障这是一种阻塞方法。当数量到达等于注册的数量时程序的执行将继续并且数量将增加。我们可以通过调用getPhase方法获取当前数量。10. ReadWriteLockReadWriteLock的具体实现是ReentrantReadWriteLockReadWriteLock允许分别创建读锁跟写锁ReadWriteLock readWriteLock new ReentrantReadWriteLock(); Lock readLock readWriteLock.readLock(); Lock writeLock readWriteLock.writeLock();使用ReadWriteLock时适用条件是同一个数据有大量线程读取但仅有少数线程修改。ReadWriteLock可以保证只允许一个线程写入其他线程既不能写入也不能读取没有写入时多个线程允许同时读提高性能读写分离锁可以有效地帮助减少锁竞争以提高系统性能,读写锁读读之间不互斥读写写写都是互斥的11. SemaphoreSemaphore 是一个计数信号量必须由获取它的线程释放。常用于限制可以访问某些资源的线程数量例如通过 Semaphore 限流。对于Semaphore来说它要保证的是资源的互斥而不是资源的同步在同一时刻是无法保证同步的但是却可以保证资源的互斥。只是限制了访问某些资源的线程数其实并没有实现同步。常用方法:1、acquire(int permits)从此信号量获取给定数目的许可在提供这些许可前一直将线程阻塞或者线程已被中断。就好比是一个学生占两个窗口。这同时也对应了相应的release方法。2、release(int permits)释放给定数目的许可将其返回到信号量。这个是对应于上面的方法一个学生占几个窗口完事之后还要释放多少3、availablePermits()返回此信号量中当前可用的许可数。也就是返回当前还有多少个窗口可用。4、reducePermits(int reduction)根据指定的缩减量减小可用许可的数目。5、hasQueuedThreads()查询是否有线程正在等待获取资源。6、getQueueLength()返回正在等待获取的线程的估计数目。该值仅是估计的数字。7、tryAcquire(int permits, long timeout, TimeUnit unit)如果在给定的等待时间内此信号量有可用的所有许可并且当前线程未被中断则从此信号量获取给定数目的许可。8、acquireUninterruptibly(int permits)从此信号量获取给定数目的许可在提供这些许可前一直将线程阻塞。12. Exchanger用于两个工作线程之间交换数据的封装工具类简单说就是一个线程在完成一定的事务后想与另一个线程交换数据则第一个先拿出数据的线程会一直等待第二个线程直到第二个线程拿着数据到来时才能彼此交换对应数据。其定义为 Exchanger 泛型类型其中 V 表示可交换的数据类型对外提供的接口很简单具体如下Exchanger()无参构造方法。V exchange(V v)等待另一个线程到达此交换点除非当前线程被中断然后将给定的对象传送给该线程并接收该线程的对象。V exchange(V v, long timeout, TimeUnit unit)等待另一个线程到达此交换点除非当前线程被中断或超出了指定的等待时间然后将给定的对象传送给该线程并接收该线程的对象。13. LockSupportLockSupport 是一个非常方便实用的线程阻塞工具他可以在任意位置让线程阻塞。LockSupport 的静态方法 park可以阻塞当前线程类似的还有 parkNanos()parkUntil(等他们实现了一个限时的等待。同样的有阻塞的方法当然有唤醒的方法什么呢unparkThread 方法。该方法可以将指定线程唤醒。需要注意的是park 方法和 unpark 方法执行顺序不是那么的严格。比如我们在 Thread 类中提到的 suspend 方法 和resume 方法如果顺序错误将导致永远无法唤醒但 park 方法和 unpark 方法则不会,因为 LockSupport 使用了类似信号量的机制。他为每一个线程准备了一个许可默认不可用如果许可能用那么 park 函数会立即返回并且消费这个许可也就是将许可变为不可用如果许可不可用将会阻塞。而 unpark 方法则使得一个许可变为可用14. AQSAQS 为 AbstractQueuedSynchronizer 的简称AQS是JDK下提供的一套用于实现基于FIFO等待队列的阻塞锁和相关的同步器的一个同步框架。这个抽象类被设计为作为一些可用原子int值来表示状态的同步器的基类。AQS管理一个关于状态信息的单一整数该整数可以表现任何状态。#比如Semaphore 用它来表现剩余的许可数ReentrantLock 用它来表现拥有它的线程已经请求了多少次锁FutureTask 用它来表现任务的状态(尚未开始、运行、完成和取消)使用须知UsageTo use this class as the basis of a synchronizer, redefine the following methods, as applicable, by inspecting and/or modifying the synchronization state using {link #getState}, {link #setState} and/or {link #compareAndSetState}:{link #tryAcquire}{link #tryRelease}{link #tryAcquireShared}{link #tryReleaseShared}{link #isHeldExclusively}以上方法不需要全部实现根据获取的锁的种类可以选择实现不同的方法:支持独占(排他)获取锁的同步器应该实现tryAcquire、 tryRelease、isHeldExclusively;支持共享获取锁的同步器应该实现tryAcquireShared、tryReleaseShared、isHeldExclusively。AQS浅析AQS的实现主要在于维护一个volatile int state代表共享资源和一个FIFO线程等待队列多线程争用资源被阻塞时会进入此队列。队列中的每个节点是对线程的一个封装包含线程基本信息状态等待的资源类型等。#state的访问方式有三种:getState()setState()compareAndSetState()#AQS定义两种资源共享方式Exclusive独占只有一个线程能执行如ReentrantLockShare共享多个线程可同时执行如Semaphore/CountDownLatch不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源state的获取与释放方式即可至于具体线程等待队列的维护如获取资源失败入队/唤醒出队等AQS已经在顶层实现好了。自定义同步器实现时主要实现以下几种方法isHeldExclusively()该线程是否正在独占资源。只有用到condition才需要去实现它。tryAcquire(int)独占方式。尝试获取资源成功则返回true失败则返回false。tryRelease(int)独占方式。尝试释放资源成功则返回true失败则返回false。tryAcquireShared(int)共享方式。尝试获取资源。负数表示失败0表示成功但没有剩余可用资源正数表示成功且有剩余资源。tryReleaseShared(int)共享方式。尝试释放资源如果释放后允许唤醒后续等待结点返回true否则返回false。以ReentrantLock为例state初始化为0表示未锁定状态。A线程lock()时会调用tryAcquire()独占该锁并将state1。此后其他线程再tryAcquire()时就会失败直到A线程unlock()到state0即释放锁为止其它线程才有机会获取该锁。当然释放锁之前A线程自己是可以重复获取此锁的state会累加这就是可重入的概念。但要注意获取多少次就要释放多么次这样才能保证state是能回到零态的。以CountDownLatch以例任务分为N个子线程去执行state也初始化为N注意N要与线程个数一致。这N个子线程是并行执行的每个子线程执行完后countDown()一次state会CAS减1。等到所有子线程都执行完后(即state0)会unpark()主调用线程然后主调用线程就会从await()函数返回继续后余动作。一般来说自定义同步器要么是独占方法要么是共享方式他们也只需实现tryAcquire-tryRelease、tryAcquireShared-tryReleaseShared中的一种即可。但AQS也支持自定义同步器同时实现独占和共享两种方式如ReentrantReadWriteLock。15. 锁基本概念公平锁/非公平锁可重入锁独享锁/共享锁互斥锁/读写锁乐观锁/悲观锁分段锁偏向锁/轻量级锁/重量级锁自旋锁公平锁/非公平锁公平锁是指多个线程按照申请锁的顺序来获取锁。非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序有可能后申请的线程比先申请的线程优先获取锁;有可能会造成优先级反转或者饥饿现象。对于Java ReentrantLock而言通过构造函数指定该锁是否是公平锁默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。对于Synchronized而言也是一种非公平锁。由于其并不像ReentrantLock是通过AQS的来实现线程调度,所以并没有任何办法使其变成公平锁。可重入锁可重入锁又名递归锁是指在同一个线程在外层方法获取锁的时候在进入内层方法会自动获取锁。ReentrantLock, Synchronized都是可重入锁。可重入锁的一个好处是可一定程度避免死锁独享(排他)锁/共享锁独享锁是指该锁一次只能被一个线程所持有。共享锁是指该锁可被多个线程所持有。对于ReentrantLock而言其是独享锁。但是对于Lock的另一个实现类ReadWriteLock其读锁是共享锁其写锁是独享锁。读锁的共享锁可保证并发读是非常高效的读写写读 写写的过程是互斥的。独享锁与共享锁也是通过AQS来实现的通过实现不同的方法来实现独享或者共享。对于Synchronized而言当然是独享锁。互斥锁/读写锁上面讲的独享锁/共享锁就是一种广义的说法互斥锁/读写锁就是具体的实现。互斥锁在Java中的具体实现就是ReentrantLock读写锁在Java中的具体实现就是ReadWriteLock乐观锁/悲观锁乐观锁与悲观锁不是指具体的什么类型的锁而是指看待并发同步的角度。悲观锁 (Synchronized 和 ReentrantLock)认为对于同一个数据的并发操作一定是会发生修改的哪怕没有修改也会认为修改。因此对于同一个数据的并发操作悲观锁采取加锁的形式。悲观的认为不加锁的并发操作一定会出问题。乐观锁 (java.util.concurrent.atomic包)认为对于同一个数据的并发操作是不会发生修改的。在更新数据的时候会采用尝试更新不断重新的方式更新数据。乐观的认为不加锁的并发操作是没有事情的。悲观锁适合写操作非常多的场景乐观锁适合读操作非常多的场景不加锁会带来大量的性能提升。悲观锁在Java中的使用就是利用各种锁。乐观锁在Java中的使用是无锁编程常常采用的是CAS算法。典型的例子就是原子类通过CAS自旋实现原子操作的更新。分段锁分段锁其实是一种锁的设计并不是具体的一种锁ConcurrentHashMap并发的实现就是通过分段锁的形式来实现高效的并发操作。ConcurrentHashMap中的分段锁称为Segment它类似于HashMapJDK7与JDK8中HashMap的实现的结构即内部拥有一个Entry数组数组中的每个元素又是一个链表同时又是一个ReentrantLockSegment继承了ReentrantLock)。当需要put元素的时候并不是对整个hashmap进行加锁而是先通过hashcode来知道他要放在那一个分段中然后对这个分段进行加锁所以当多线程put的时候只要不是放在一个分段中就实现了真正的并行的插入。但是在统计size的时候可就是获取hashmap全局信息的时候就需要获取所有的分段锁才能统计。分段锁的设计目的是细化锁的粒度当操作不需要更新整个数组的时候就仅仅针对数组中的一项进行加锁操作。偏向锁/轻量级锁/重量级锁这三种锁是指锁的状态并且是针对Synchronized。在Java 5通过引入锁升级的机制来实现高效Synchronized。这三种锁的状态是通过对象监视器在对象头中的字段来表明的。偏向锁是指一段同步代码一直被一个线程所访问那么该线程会自动获取锁。降低获取锁的代价。轻量级锁是指当锁是偏向锁的时候被另一个线程所访问偏向锁就会升级为轻量级锁其他线程会通过自旋的形式尝试获取锁不会阻塞提高性能。重量级锁是指当锁为轻量级锁的时候另一个线程虽然是自旋但自旋不会一直持续下去当自旋一定次数的时候还没有获取到锁就会进入阻塞该锁膨胀为重量级锁。重量级锁会让其他申请的线程进入阻塞性能降低。自旋锁在Java中自旋锁是指尝试获取锁的线程不会立即阻塞而是采用循环的方式去尝试获取锁这样的好处是减少线程上下文切换的消耗缺点是循环会消耗CPU。典型的自旋锁实现的例子可以参考自旋锁的实现原文作者牧小农原文链接https://segmentfault.com/a/1190000023961648原文出处CSDN
http://www.ihoyoo.com/news/76665.html

相关文章:

  • 呼市推广网站中国诗歌网个人网页
  • 湛江做网站企业网站 实名认证
  • 政务网站开发帮助中心网站源码
  • wordpress建站知乎西乡做网站哪家便宜
  • 网站更换内容深圳深圳建设网站
  • 网易网站开发淘宝客网站推广备案
  • 阜阳建网站收费网站有哪些
  • 虚拟主机如何做多个网站什么是网络设计与电子商务
  • 阿里云虚拟主机可以做几个网站吗页面设计费用
  • 网站关于我们页面设计高端网站建设公司兴田德润在那里
  • 现如今网站开发用什么框架动画设计公司
  • 河南网站建设SEO优化制作设计公司asp网站目录权限
  • wordpress调用指定分类的文章列表福州百度seo代理
  • 深圳找工作哪个网站好青岛市南区城市建设局网站
  • 网站设计计划书的要求广州网站快速优化排名
  • 温州网站升级重庆营销型网站随做的好处
  • html做的网站图片横着摆放摄影欣赏网站哪个最好
  • 加强健康养老网站建设网站开发的需求分析教学视频
  • 芜湖市建设工程质量监督站官方网站网络推广方案怎么写
  • 网站美工做确认取消对话框wordpress 免密码
  • 商城网站建设的优点简单的个人网页制作
  • 潍坊建站公司手机建公司网站
  • 查询网站备案进度32强世界排名
  • 建网站需要多少钱2017杭州网站设计步骤
  • 有没有跟一起做网店一样的网站用网址进入的游戏
  • 做购物网站需要什么山西+网站建设
  • 网站结构设计的内容温州网站建设小公司
  • 网站如果不续费会怎样html5导航网站源码
  • 山西省建设厅招标网站网站怎么添加广告代码
  • 淄博建网站哪家好网站设计 现在流行的导航方式