java 线程之对象的同步和异步(实例讲解)

下面小编就为大家带来一篇java 线程之对象的同步和异步(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

一、多线程环境下的同步与异步

同步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为同步机制存在,A线程请求不到,怎么办,A线程只能等待下去。

package com.jalja.org.thread.demo01;

public class Thread02 {
 public synchronized void method1(){
  System.out.println("method1:"+Thread.currentThread().getName());
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 public synchronized void method2(){
  System.out.println("method2:"+Thread.currentThread().getName());
 }
 public static void main(String[] args) {
  final Thread02 th=new Thread02();
  Thread thread1=new Thread(new Runnable() {
   public void run() {
    th.method1();
   }
  },"th1");

  Thread thread2=new Thread(new Runnable() {
   public void run() {
    th.method2();
   }
  },"th2");

  thread1.start();
  thread2.start();
 }
}

观察输出结果:method1:th1 在3秒后 method2:th2 输出,这是因为method2() 与 method1()都是同步方法,而线程thread1 与 thread2操作的是同一个对象th,所以thread2在执行method2()方法时,需要先获得到th对象的锁。 异步:A线程要请求某个资源,但是此资源正在被B线程使用中,因为没有同步机制存在,A线程仍然请求的到,A线程无需等待。

package com.jalja.org.thread.demo01;

public class Thread02 {
 public synchronized void method1(){
  System.out.println("method1:"+Thread.currentThread().getName());
  try {
   Thread.sleep(3000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
 }
 public void method2(){
  System.out.println("method2:"+Thread.currentThread().getName());
 }
 public static void main(String[] args) {
  final Thread02 th=new Thread02();
  Thread thread1=new Thread(new Runnable() {
   public void run() {
    th.method1();
   }
  },"th1");

  Thread thread2=new Thread(new Runnable() {
   public void run() {
    th.method2();
   }
  },"th2");

  thread1.start();
  thread2.start();
 }
}

观察输出结果:method1:th1 与 method2:th2 同时输出,这是因为method2 没有加同步控制,所以线程thread2在执行method2()方法时不用去获得执行权限(对象锁)。

二、数据的脏读

我们在设计业务的时候一定要考虑业务的整体性,不然就会出现数据一致性问题。

package com.jalja.org.thread.demo01;

public class Thread03 {
 private String name="zs";
 private String passWorrd="123";
 public synchronized void setValue(String name,String passWord){
  this.name=name;
  try {
   Thread.sleep(2000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  this.passWorrd=passWord;
  System.out.println("set:name="+this.name +" passWorrd="+this.passWorrd);
 }
 public void getValue(){
  System.out.println("get:name="+this.name +" passWorrd="+this.passWorrd);
 }
 public static void main(String[] args) throws InterruptedException {
  final Thread03 th=new Thread03();
  Thread thread=new Thread(new Runnable() {
   public void run() {
    th.setValue("LS", "456");
   }
  });
  thread.start();
  Thread.sleep(100);
  th.getValue();
 }
}

结果:get:name=LS passWorrd=123 set:name=LS passWorrd=456 由结果可知get的数据显然有问题,这是因为thread线程在set的时候,main线程在执行get方法。想要避免这种情况,我们就要保证当有线程在操作同一个对象的数据时,就不然其他线程也同时操作该对象的数据。这个情况我们在get方法上加 synchronized 关键字即可。

https://m.jb51.net/article/119103.htm

本文分享自微信公众号 - 挨踢小子(LN-aitixiaozi)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏洛米唯熊

用Everything下可能导致的信息泄露

Everything是一款免费快速的文件搜索引擎,用于快速搜索特定名称的文件和文件夹,在你输入以后,瞬间会找到并显示匹配列表,是超越win自带搜索几光年...

51420
来自专栏玩转JavaEE

Spring Boot 结合 WebSocket 实现在线聊天

要说 WebSocket 协议,我们得先来说说 HTTP 协议的一个请求头,事实上,所有的 HTTP 客户端(浏览器、移动端等)都可以在请求头中包含 Conne...

13420
来自专栏陶士涵的菜地

[Linux] deepin系统添加PHP仓库源出错Error: could not find a distribution template for Deepin/stable

aptsources.distro.NoDistroTemplateException: Error: could not find a distributio...

11310
来自专栏SAP ERP管理实践

SAP中如何找增强点

CALL METHOD cl_exithandler=>get_class_name_by_interface后面设置一个断点。然后执行业务事务代码如MIRO,...

8610
来自专栏云端漫步

GET和POST的区别

这是百度搜索答案TOP1,通过查阅官方资料。发现答案基本是错的,下面根据答案逐一分析:

9620
来自专栏Java后端技术栈cwnait

++i和i++仅仅是先加1和后加1的区别吗?

关于前置++与后置++的差别,这似乎再熟悉不过了。前置++ 是先将变量的值加1,然后使用加1后的值参与运算。而后置++ 是先使用该值参与运算,然后再将该值加1。

12220
来自专栏coding

搭建sentry追踪laravel生产环境bug

未上线的代码无论再测试,也不可能保证全无 bug ,很多 bug 一直隐藏在某个阴暗的角落,邪恶又猥琐地等着你将其部署上线,然后在某个条件的触发下,开始兴风作浪...

10510
来自专栏Ms08067安全实验室

【VulnHub】Raven: 2 靶机的渗透测试

4. 查看wordpress的wp-config.php配置文件得到数据库账号密码

13430
来自专栏生信技能树

ChIP‐Atlas(逆向收费读文献2019-21)

本次分享的文献发表了一个网页数据库,把其它数据库(GEO, ArrayExpress, DDBJ, ENCODE等等)的表观数据(主要是ChIP-seq and...

9820
来自专栏Linux知识积累

创建 REST API 的最佳入门教程

如果你看到这里,你以前可能听说过API 和REST,然后你就会想:“这些都是什么东西?”。也许你已经了解过一些这方面的知识,但却不知道从何入手。在这个教程中,我...

11720

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励