知识大全 关于JAVA多线程并发synchronized的测试与合理使用

Posted hr

篇首语:只会幻想而不行动的人,永远也体会不到收获果实时的喜悦。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 关于JAVA多线程并发synchronized的测试与合理使用相关的知识,希望对你有一定的参考价值。

关于JAVA多线程并发synchronized的测试与合理使用  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  在项目开发中 或许会碰到JAVA的多线程处理 为保证业务数据的正常 必须加上锁机制   常用的处理方法一般是加上synchronized关键字 目前JDK版本对synchronized已经做了很好的优化   我们不用再考虑其性能   但在实际使用中   往往由于处理不当   导致系统性能的严重下降 那么该如何合理的使用synchronized   必须对其使用方式有个全面了解 在网上搜寻的资料 给出的是四种使用方式 其实可总结为两种 一个是同步代码块 一个是同步方法体 那么该如何使用 请看下面的测试

  准备两个方法   对同一个变量做加法 再对每个方法 分别开十个线程执行

  [java]

  public class ThreadUnit

  

  private int i = ;

  private Object obj = new Object()

  private Object obj = new Object()

  public synchronized Integer doAdd (Long start) throws Exception

  

  Thread sleep( )

  ++i;

  Thread sleep( )

  return i;

  

  public Integer doAdd (Long start) throws Exception

  

  Thread sleep( )

  ++i;

  Thread sleep( )

  return i;

  

  

  相关代码

  [java]

  // 十个线程同时执行方法

  for (int i = ; i < ; i++)

  

  new Thread(new MessageThread( threadUnit)) start()

  

  // 十个线程同时执行方法

  for (int j = ; j < ; j++)

  

  new Thread(new MessageThread( threadUnit)) start()

  

  线程处理

  [java]

  public void run()

  

  try

  

  if (operate == )

  

  long start = System currentTimeMillis()

  int i = threadUnit doAdd (start)

  long takeTime = System currentTimeMillis() start;

  System out println( doAdd () => i= + i + spendTime= + takeTime + ms )

  spendTime += takeTime;

  

  else

  

  long start = System currentTimeMillis()

  int i = threadUnit doAdd (start)

  long takeTime = System currentTimeMillis() start;

  System out println( doAdd () => i= + i + spendTime= + takeTime + ms )

  spendTime += takeTime;

  

  

  catch (Exception e)

  

  e printStackTrace()

  

  

  运行结果

   在两个方法体上都加上synchronized

  [java]

  public synchronized Integer doAdd (Long start) throws Exception

  [java]

  public synchronized Integer doAdd (Long start) throws Exception

  执行结果

  []

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  花费时间 ms

  都是有序执行 变量值没有产生错乱 但花费时间 ms

   在doAdd 方法上加上synchronized doAdd 不加

  [java]

  public synchronized Integer doAdd (Long start) throws Exception

  执行结果

  [java]

  doAdd 方法加上synchronized:

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  花费时间 ms

  doAdd 方法瞬间执行完成 之后doAdd 方法则是串行有序执行 这时doAdd 方法获取的变量值已经错乱   doAdd 获取的正常   花费时间 ms

   两个方法在都没使用synchronized前的情况

  执行结果

  [java]

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  花费时间 ms

  可以看到 两个方法的变量值获取已经错乱   但花费时间最少 ms

   使用同步块 在两个方法内采用不同的对象锁

  doAdd :

  [java]

  synchronized (obj )

  

  Thread sleep( )

  ++i;

  Thread sleep( )

  return i;

  

  doAdd :

  [java]

  synchronized (obj )

  

  Thread sleep( )

  ++i;

  Thread sleep( )

  return i;

  

  执行结果

  []

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  花费时间 ms

  两个方法有序交替执行 互不影响   花费时间 ms 相对加锁同一对象执行的时间缩短

   使用同步块 使用方法参数作为对象锁

  [java]

  public Integer doAdd (Long start) throws Exception

  

  synchronized (start)

  

  Thread sleep( )

  ++i;

  Thread sleep( )

  return i;

  

  

  执行结果

  [java]

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  花费时间 ms

  执行效果和第三种情况相同   每个参数作为不同的对象 即便加上synchronized也不能起到锁的效果

   把调用的类改为静态类 只在一个方法上加锁

  加锁doAdd 方法

  [java]

  public static synchronized Integer doAdd (Long start) throws Exception

  执行结果

  []

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  doAdd () => i= spendTime= ms

  花费时间 ms

  和第二种情形类似   没有加锁的doAdd 方法瞬间执行完成   doAdd 方法则是串行有序执行

  总结

   synchronized关键在于锁定的对象 如果是同一对象 那么所有执行线程 必须等待对象锁释放后才能执行   如果是不同对象   那么只对各对象所关联的线程生效

   synchronized若加在方法体上   默认锁定的是对象本身 对于所有加锁的方法   都是按照串行规则有序执行   对于没有加锁的方法 不受任何影响   静态类同理

   合理使用synchronized 既要保证稳定性 又要保证性能 需要在两者间作出权衡   尽量把synchronized范围细度化 合理控制业务处理流程   对象操作原子化 减少锁的使用

cha138/Article/program/Java/gj/201311/27586

相关参考

知识大全 java多线程中synchronized关键字的用法

  由于同一进程内的多个线程共享内存空间在Java中就是共享实例当多个线程试图同时修改某个实例的内容时就会造成冲突因此线程必须实现共享互斥使多线程同步  最简单的同步是将一个方法标记为synchron

知识大全 使用Synchronized块同步方法

Java多线程初学者指南(11):使用Synchronized块同步方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们

知识大全 使用Synchronized块同步方法

初学Java多线程:使用Synchronized块同步方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 使用Synchronized块同步变量

Java多线程初学者指南(12):使用Synchronized块同步变量  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们

知识大全 使用Synchronized关键字同步类方法

初学Java多线程:使用Synchronized关键字同步类方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起

知识大全 使用Synchronized关键字同步类方法

Java多线程初学者指南(10):使用Synchronized关键字同步类方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,

知识大全 java关于多线程的部分操作

  一般服务器端代码每次收到一个线程一个client就会产生  /************************开始监听**************************/  intport=; 

知识大全 关于Java多线程技术中所有方法的详细解析

Java进阶:关于Java多线程技术中所有方法的详细解析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下

知识大全 用java多线程断点续传实践

  /**  *authorannegu  *date  */  annegu做了一个简单的Http多线程的下载程序来讨论一下多线程并发下载以及断点续传的问题  这个程序的功能就是可以分多个线程从目标

知识大全 关于线程的停止问题

  多线程是java的一个优势java使得程序员可以很方便的进行多线程程序开发获得更好的性能  关于多线程的概念以及一般的多线程编程比如如何以及为何实现runnable接口为何stop()会被Depr