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后端接入微信小程序登录功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • Spring的@ComponentScan注解用法介绍

    Spring的@ComponentScan注解用法介绍

    这篇文章主要介绍了Spring的@ComponentScan注解用法介绍,@ComponentScan注解一般和@Configuration注解一起使用,主要的作用就是定义包扫描的规则,然后根据定义的规则找出哪些需类需要自动装配到spring的bean容器中,然后交由spring进行统一管理,需要的朋友可以参考下
    2023-11-11
  • SpringBoot JPA 表关联查询实例

    SpringBoot JPA 表关联查询实例

    本篇文章主要介绍了SpringBoot JPA 表关联查询实例,使用JPA原生的findBy语句实现,具有一定的参考价值,有兴趣的可以了解一下。
    2017-04-04
  • 详解springboot-mysql-pagehelper分页插件集成

    详解springboot-mysql-pagehelper分页插件集成

    这篇文章主要介绍了springboot-mysql-pagehelper分页插件集成,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Java Gradle项目中的资源正确获取方式

    Java Gradle项目中的资源正确获取方式

    这篇文章主要介绍了Java Gradle项目中的资源正确获取方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • 浅谈JVM之类的加载链接和初始化

    浅谈JVM之类的加载链接和初始化

    有了java class文件之后,为了让class文件转换成为JVM可以真正运行的结构,需要经历加载,链接和初始化的过程。这三个过程是怎么工作的呢?在本文中你将会找到答案。
    2021-06-06
  • Java实现对象转CSV格式

    Java实现对象转CSV格式

    CSV是一种逗号分隔值格式的文件,一般用来存储数据的纯文本格式文件。Java对象转CSV,有现成的工具包,commons-lang3 的ReflectionToStringBuilder 就可以简单的解决的对象转CSV,快跟随小编一起学习一下吧
    2022-06-06
  • springMVC之HandlerExceptionResolver使用

    springMVC之HandlerExceptionResolver使用

    这篇文章主要介绍了springMVC之HandlerExceptionResolver使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • @PathParam和@QueryParam区别简析

    @PathParam和@QueryParam区别简析

    这篇文章主要介绍了@PathParam和@QueryParam区别,分享了相关实例代码,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • Java的SpringMVC中控制器返回XML数据问题

    Java的SpringMVC中控制器返回XML数据问题

    这篇文章主要介绍了Java的SpringMVC中控制器返回XML数据问题,控制器是处理HTTP请求的组件,它们接收来自客户端的请求,并将其转换为适当的响应,这些响应可以是动态生成的 HTML 页面,也可以是JSON或XML格式的数据,需要的朋友可以参考下
    2023-07-07

最新评论