1. 多线程场景下尽量使用并发容器代替同步容器

  (如ConcurrentHashMap代替同步且基于散列的Map, 遍历操作为主要操作的情况下用CopyOnWriteArrayList代替同步的List)

  ConcurrentHashMap:分段锁机制,多线程条件下优于HashMap+synchronized的组合方式;
  CopyOnWriteArrayList: 每次修改时都会创建并重新发布一个新的容器副本,从而实现可变性。容器的迭代器保留一个指向底层基础数组的引用,这个数组当前位于迭代器的起始位置,由于他不会被修改,
所以在对其进行同步时只需确保数组内容的可见性。
2. 避免死锁
  a)尽量不要在释放锁之前竞争其他锁:一般可以通过细化同步方法来实现,只在真正需要保护共享资源的地方去拿锁,并尽快释放锁,这样可以有效降低在同步方法里调用其他同步方法 的情况
  b)顺序索取锁资源: 如果实在无法避免嵌套索取锁资源,则需要制定一个索取锁资源的策略,先规划好有哪些锁,然后各个线程按照一个顺序去索取
  c)尝试定时锁: Java 5提供了更灵活的锁工具,可以显式地索取和释放锁。那么在索取锁的时候可以设定一个超时时间,如果超过这个时间还没索取到锁,则不会继续堵塞而是放弃此次任务,如下:

public boolean trySendOnSharedLine(String message, long timeout, TimeUnit unit) throws InterruptedException {
long nanosToLock = unit.toNanos(timeout) - estimatedNanosToSend(message);
if (!lock.tryLock(nanosToLock, NANOSECONDS)){
return false;
}
try {
return sendOnSharedLine(message);
} finally {
lock.unlock();
}
} 

这样可以效打破死锁条件。
3. Amdahl定理:
  speedup<= 1/(F+(1-F)/N)
  其中,F是串行化比例,N是处理器数量,由上可知,只有尽可能减少串行化,才能最大化地提高可扩展能力。降低串行化的关键就是降低锁竞争,当很多并行任务挂在锁的获取上,就是串行化的表现.
4. 降低锁竞争
  1)缩小锁的范围
    尽量缩小锁保护的范围,快进快出,因此尽量不要直接在方法上使用synchronized关键字,而只是在真正需要线程安全保护的地方使用
  2)减小锁的粒度
    尽量避免大段的synchronize代码块
  3)减少共享资源的依赖
    在多线程开发中尽量减少对共享资源的依赖,比如对象池的技术应该慎重考虑,新的JVM对新建对象以做了足够的优化,性能非常好,如果用对象池不但不能提高多少性能,反而 会因为锁竞争导致降低线程的可并发性。
  4)使用读写分离锁来替换独占锁
    Java 5提供了一个读写分离锁(ReadWriteLock)来实现读-读并发,读-写串行,写-写串行的特性。这种方式更进一步提高了可并发性,因为有些场景大部分是读操作,因此没必要串行工作。
5. 切换上下文
  线程比较多的时候,操作系统切换线程上下文的性能消耗是不能忽略的,
6. 内存同步
  当使用到synchronized、volatile或Lock的时候,都会为了保证可见性导致更多的内存同步,这就无法享受到JMM结构带来了性能优化。
7. 适当使用同步工具类
  (1) 闭锁(CountDownLatch): 延迟线程的进度直到其达到终止状态,用来确保某些活动直到其他活动都完成后才继续执行;一次性对象,一旦进入终止状态,就不能被重置;
  (2) FutureTask: 可生成结果的Callable,如果有结果可用,那么FutureTask.get将立即返回结果,否则它会一直阻塞,直到结果计算出来再将其返回。
  (3) 信号量(Semaphore):用来控制同时访问某个特定资源的操作数量,或者同时某个指定操作的数量,Semaphore还可以用来实现某种资源池,或者对容器施加边界。
  (4) 栅栏(Barrier): 类似于闭锁,区别在于所有线程必须同时到达栅栏位置才能继续执行,闭锁用于等待事件,而栅栏用于等待其他线程。可被重置用于下次使用。两种实现方式:CyclicBarrier,Exchanger

8. 实际情况中,应尽可能的使用现有的线程安全对象(例如AtomicInteger)来管理类的状态

9. 在多线程程序中使用共享且可变的long和double等类型的变量也是不安全的,除非用volatile来声明它们,或者用锁保护起来。

JAVA并发编程学习笔记------多线程调优的更多相关文章

  1. Java并发编程学习笔记

    Java编程思想,并发编程学习笔记. 一.基本的线程机制 1.定义任务:Runnable接口 线程可以驱动任务,因此需要一种描述任务的方式,这可以由Runnable接口来提供.要想定义任务,只需实现R ...

  2. Java并发编程学习笔记 深入理解volatile关键字的作用

    引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深入研究一下java并发方面的知识.网上关于volatile的 ...

  3. Java 并发编程学习笔记 理解CLH队列锁算法

    CLH算法实现 CLH队列中的结点QNode中含有一个locked字段,该字段若为true表示该线程需要获取锁,且不释放锁,为false表示线程释放了锁.结点之间是通过隐形的链表相连,之所以叫隐形的链 ...

  4. Java并发编程学习笔记(一)——线程安全性

    主要概念:线程安全性.原子性.原子变量.原子操作.竟态条件.复合操作.加锁机制.重入.活跃性与性能. 1.当多个线程访问某个状态变量并且其中有一个线程执行写入操作时,必须采用同步机制来协同这些线程对变 ...

  5. JAVA并发编程学习笔记------对象的可见性及发布逸出

    一.非原子的64位操作: 当线程在没有同步的情况下读取变量时,可能会得到一个失效值,但至少这个值是由之前某个线程设置的值,而不是一个随机值,这种安全性保证被称为最低安全性.最低安全性适用于绝大多数变量 ...

  6. [转]JAVA并发编程学习笔记之Unsafe类

    1.通过Unsafe类可以分配内存,可以释放内存:类中提供的3个本地方法allocateMemory.reallocateMemory.freeMemory分别用于分配内存,扩充内存和释放内存,与C语 ...

  7. Java并发编程学习笔记(三)——对象的组合

    重要概念: 1.在设计线程安全类的过程中,需要包含以下三个基本要素: (1)找出构成对象状态的所有变量. (2)找出约束状态变量的不变性条件. (3)建立对象状态的并发访问管理策略. 2.

  8. Java并发编程学习笔记(二)——对象的共享

    主要概念:可见性.重排序.失效数据.最低安全性.发布.逸出.线程封闭(Ad-hoc.栈封闭.ThreadLocal类).不变性.Final域.事实不可变对象. 1.在没有同步的情况下,编译器.处理器以 ...

  9. java并发编程学习笔记(一)初识并发原子性

    1.并发的意义 现在是一个多核的时代,并发的存在意义就是为了能够充分利用多核计算机的优势,提高程序的运行效率: 2.并发的风险 竞争-----多个线程对内存数据数据进行读写操作时,对数据处理结果的一个 ...

随机推荐

  1. 01 Maven 安装与配置

    Maven 安装与配置 1. Maven 介绍 Maven 翻译为 "专家","内行".Maven 是 Apache 下的一个纯 Java 开发的开源项目,它是 ...

  2. 20155328 2016-2017-2 《Java程序设计》第7周学习总结

    20155328 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 时区 Date与DateFormat Date只用来获取epoch毫秒数 DateForma ...

  3. Axios的基本使用

    Axios的基本使用 介绍 Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中.在vue 中,用来发ajax请求,与后端交互. 从浏览器中创建 XMLHtt ...

  4. Windows10和CentOS7双系统安装的一些小技巧

    我个人是先安装好了win10系统,且win10是单独在一个120g的盘里:而centOS7则是安装在另一个500g的磁盘的其中的380g里: 这里要着重注意的是,500g里分成380g的盘不要在win ...

  5. git图解:代码区域总结

    本文背景,在实际项目中使用git已有一年多,发现不少同事虽然会使用常用git指令,但并不理解每个指令对应的作用原理.今天静下心总结下git 的基本理解:代码的存在区域:本文以实际项目出发,理清使用gi ...

  6. calltree+graphviz 绘出项目函数调用图

    install calltree: download from http://linux.softpedia.com/progDownload/calltree-Download-971.html f ...

  7. sine

       

  8. 如何实现让你的网站支持Google Roboto Font

    最近在写一个移动端的web项目,designer设计的页面效果图就是使用Google Roboto Font.The Roboto Font 是Google为Android 4.0 Ice-Cream ...

  9. 【Win10】开发中的新特性及原有的变更(二)

    声明:本文内容适用于 Visual Studio 2015 RC 及 Windows 10 10069 SDK 环境下,若以后有任何变更,请以新的特性为准. 十一.x:Bind 中使用强制转换 这点是 ...

  10. VS2012 中不能安装ARCGIS 10.0 SDK的解决方法

    问题描述 在ARCGIS 安装SDK时 就会出错   原因是ARCGIS SDK 10.0只能在VS2010中安装,因为我本机是安的VS2012所以安装不成功.     解决方法 一,在注册表中HKE ...