zoukankan      html  css  js  c++  java
  • 多线程性能分析

    如果越多的资源被消耗在锁的管理和调度上,那么应用程序得到的资源就越少。
    锁的实现方式越好,将需要越少的系统调用和上下文切换,并且在共享内存总线上的内存同步通讯量越少。

    线程引入的开销

    上下文切换:
    	线程调度需要访问由操作系统和JVM共享的数据结构。
    
    	如果新的线程被切换进来,所需要的数据不在当前处理器的本地缓存中,
    	上下文切换将导致一些缓存缺失,因而线程在首次调度运行时会更加缓慢。
    
    	频繁的IO操作(阻塞)将增加线程的上下文切换。
    
    
    内存同步:
    	synchronized 和 volatile 提供的可见性保证中可能会使用一些特殊指令,即内存栅栏。
    	内存栅栏可以刷新缓存,抑制指令重排。
    	内存栅栏抑制编译器的优化,对性能产生间接影响。
    

    非公平锁性能高于公平锁

    恢复一个被挂起的线程与该线程真正开始运行存在者严重的延迟。
    
    非公平锁允许插队,可以避免这种延迟。
    
    如果锁的持有时间较长,则应该使用公平锁,因为非公平锁带来的吞吐量提升可能不会出现。
    

    减少锁竞争

    1. 减少锁的持有时间:使用同步代码块
    2. 降低锁的请求频率:锁分解和锁分段
    3. 放弃独占锁:使用并发容器,读写锁,不可变对象,原子变量。
    
    
    锁分解:
    	如果一个锁需要保护多个相互独立的状态变量,那么可以将这个锁分解为多个锁,每个锁只保护一个变量
    
    
    锁分段:
    	劣势:获取多个锁实现独占访问时,获取更加困难并且开销更大。比如 jdk1.7 之前 ConcurrentHashMap 的 size() 操作。
    

    ReentrantLock(显式锁)

    轮询锁和定时锁:
    	通过 tryLock() 实现(内置锁无法中断一个正在等待获取锁的线程)
    
    可中断的锁获取操作:
    	lockInterruptibly() 能够在获取锁的同时保持对中断的响应(定时的 tryLock() 同样能响应中断)
    

    Concurrent性能和可伸缩性优于synchronized的原因

    原子变量与非阻塞同步机制
    
    
    原子变量:
    	使用CAS机制。
    
    
    非阻塞同步机制(CAS):
    	一个线程的失败或挂起不会导致其他线程的失败或挂起。
    	非阻塞的栈和链表等。
    
    
    悲观锁(synchronized和ReentrantLock):
    	始终获取锁(独占锁),失败则阻塞。
    	适合多写的情况(竞争大)。
    
    乐观锁(atomic包):
    	不上锁,通过冲突检查机制(CAS)判断在更新过程中是否存在其他线程干扰,操作失败可以重试。
    	适用于多读的应用类型(很少发生冲突),这样可以提高吞吐量。
    
    	缺点:
    		ABA问题
    		循环开销大(不成功一直循环)
    		只能保证一个共享变量的原子操作
    
  • 相关阅读:
    js函数柯理化
    Promise异步编程解决方案
    set和map结构,class类
    原创:用node.js搭建本地服务模拟接口访问实现数据模拟
    原创:微信小程序如何使用自定义组件
    原创:微信小程序开发要点总结
    Nodejs CMS——基于 NestJS/NuxtJS 的完整开源项目
    浅谈js对象之数据属性、访问器属性、Object.defineProperty方法
    Promise初步详解(resolve,reject,catch)
    原生js面向对象实现简单轮播
  • 原文地址:https://www.cnblogs.com/loveer/p/11745201.html
Copyright © 2011-2022 走看看