Java 中synchronize函数的实例详解

 更新时间:2017年09月18日 11:17:20   投稿:lqh  
这篇文章主要介绍了Java 中synchronize函数的实例详解的相关资料,希望通过本文能帮助到大家理解使用synchronize函数的使用方法,需要的朋友可以参考下

Java 中synchronize函数的实例详解

java中的一个类的成员函数若用synchronized来修饰,则对应同一个对象,多个线程像调用这个对象的这个同步函数时必须等到上一个线程调用完才能由下一个线程调用。

那么如果一个类同时有两个成员函数是由synchronized修饰如代码所示,对与同一个对象,是否可以在两个线程运行时,一个调用funcA,同时另一个调用funcB?

Mysyn是这样一个类,如果我有两个线程,一个在run方法中先运行funcA再运行funcB,另一个线程在run方法中先运行funcB再运行funcA。那有没有可能出现这样的情况:在输出时start A...后面直接输出start B...?

public class MySyn { 
  public synchronized void funcA(String str){ 
    System.out.println(str+":"); 
    System.out.println("start A..."); 
    try { 
      Thread.sleep(5000); 
    } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
    System.out.println("...A end"); 
  } 
   
  public synchronized void funcB(String str){ 
    System.out.println(str+":"); 
    System.out.println("start B..."); 
    try { 
      Thread.sleep(5000); 
    } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
    System.out.println("...B end"); 
  } 
} 

测试代码如下:

这个线程是先运行funcA的

public class Mythread implements Runnable { 
 
  private MySyn mysyn; 
  private String id; 
  public Mythread(MySyn syn, String id){ 
    this.mysyn = syn; 
    this.id = id; 
  } 
  @Override 
  public void run() { 
     
    this.mysyn.funcA(id); 
    try { 
      Thread.sleep(1000); 
    } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
    } 
    this.mysyn.funcB(id); 
  } 
   
  public static void main(String arg[]){ 
    MySyn syn=new MySyn(); 
    Thread t1 = new Thread(new Mythread(syn, "t1")); 
    Thread t2 = new Thread(new YourThread(syn, "t2")); 
     
     
    t1.start(); 
    t2.start(); 
  } 
 
} 

这个线程是先运行funcB的

public class YourThread implements Runnable { 
 
  private MySyn mysyn; 
  private String id; 
  public YourThread(MySyn syn, String id){ 
    this.mysyn = syn; 
    this.id=id; 
  } 
  @Override 
  public void run() { 
    this.mysyn.funcB(id); 
    this.mysyn.funcA(id); 
     
 
  } 
 
} 

输出结果多是:

t1: 
start A... 
...A end 
t2: 
start B... 
...B end 
t2: 
start A... 
...A end 
t1: 
start B... 
...B end 

如果取消Mythread的run方法中两个函数调用间的sleep,那结果多是:

t1: 
start A... 
...A end 
t1: 
start B... 
...B end 
t2: 
start B... 
...B end 
t2: 
start A... 
...A end 

个人结果可能因线程调度不同,但是永远不会有:start A...后面直接输出start B...

那如果funcB不是一个同步函数,那上述代码运行结果会是怎么样呢?

代码稍加改动,把funcB的synchronized关键字去掉。运行结果为:

t2: 
t1: 
start A... 
start B... 
...A end 
t1: 
start B... 
...B end 
t2: 
start A... 
...B end 
...A end 

显然出现了start A...后面直接输出start B...的结果。

同样如果Mysyn类如果有一个public 的成员变量,多线程也可以再同步函数被调用的同时,由另一个线程修改这个成员变量。

上述实验说明了:同步的成员函数只能在同一个对象的同步函数调用中对其他同步函数(包括本身)有排它的效果,即多线程运行中,同一个对象当前只能有一个同步函数在运行,但不排除其他非同步函数的运行或对成员进行访问。

 那现在假设某个类有两个静态同步方法,那情况怎么样呢?

具体实现,我就不重复了,因为结果类似:

在多线程中,同一个类,当前只能有一个类同步函数(静态同步函数)在运行,但不排除其他非同步静态函数的运行或对静态成员的访问

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

相关文章

  • 基于Java方式实现数据同步

    基于Java方式实现数据同步

    这篇文章主要为大家详细介绍了基于Java方式实现数据同步,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • Java操作另一个Java程序使其重启的简单实现

    Java操作另一个Java程序使其重启的简单实现

    下面小编就为大家带来一篇Java操作另一个Java程序使其重启的简单实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • Java实现导出Excel功能

    Java实现导出Excel功能

    通过java中Controller层,来接受请求,数据库查询到的数据进行封装,然后使用ExcelUtils进行输出,接下来通过本文给大家分享Java实现导出Excel功能的实例代码,感兴趣的朋友跟随小编一起看看吧
    2021-11-11
  • intellij idea隐藏.iml和.idea等自动生成文件的问题

    intellij idea隐藏.iml和.idea等自动生成文件的问题

    这篇文章主要介绍了intellij idea隐藏.iml和.idea等自动生成文件的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 关于mybatis resulttype 返回值异常的问题

    关于mybatis resulttype 返回值异常的问题

    这篇文章主要介绍了mybatis resulttype 返回值异常的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 开发工具EesyCode使用方法解析

    开发工具EesyCode使用方法解析

    这篇文章主要介绍了开发工具EesyCode使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java代码生成器的制作流程详解

    Java代码生成器的制作流程详解

    这篇文章主要介绍了Java代码生成器的制作流程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 基于Spring中的事务@Transactional细节与易错点、幻读

    基于Spring中的事务@Transactional细节与易错点、幻读

    这篇文章主要介绍了基于Spring中的事务@Transactional细节与易错点、幻读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 详解Java信号量Semaphore的原理及使用

    详解Java信号量Semaphore的原理及使用

    Semaphore来自于JDK1.5的JUC包,直译过来就是信号量,被作为一种多线程并发控制工具来使用。本文将详解其原理与使用方法,感兴趣的可以学习一下
    2022-05-05
  • 详解tryAcquire()、addWaiter()、acquireQueued()

    详解tryAcquire()、addWaiter()、acquireQueued()

    这篇文章主要tryAcquire()、addWaiter()、acquireQueued()的用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03

最新评论