首先是一段代码:

 public class HasSelfPrivateNum {
public void addI(String username){
try {
int num=0;
if(username.equals("a")){
num=100;
System.out.println("a set over! ");
Thread.sleep(2000);
}else{
num=200;
System.out.println("b set over! ");
}
System.out.println(username+" num="+num);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

上述代码中的含义是HasSelfPrivateNum对象的A和B的判断

之后有两个线程:

 public class ThreadA extends Thread {
private HasSelfPrivateNum numRef;
public ThreadA(HasSelfPrivateNum numRef){
super();
this.numRef=numRef;
} public void run(){
super.run();
numRef.addI("a");
}
}
 public class ThreadB extends Thread{
private HasSelfPrivateNum numRef;
public ThreadB(HasSelfPrivateNum numRef){
super();
this.numRef=numRef;
} public void run(){
super.run();
numRef.addI("b");
}
}

我们可以看出来线程A和线程B中我们创建了HasSelfPrivateNum实例。

运行结果中可以看出来,这个程序不存在非线程安全性问题,为什么呢,因为这个变量是方法内部的,方法内部的变量是私有的特性造成了线程安全,并且这个其本身永远线程安全。接下来吧int num这一行代码放在方法之外我们会看到什么呢?

这时我们会看到线程不安全了,两个对象同时操作了业务中的实例变量,所以发生了线程不安全的问题,原因是没有同步,为了让线程安全我们可以家一个同步锁来解决这个问题:

加了同步锁之后运行就安全了,直到A线程执行完成之后在会执行B线程,如果一个线程没有执行完毕,那么其他线程就无法访问这个线程。和之前那个同步锁的道理是一样的,这就是线程的同步.

以上就是线程同步的道理;

下面是线程的异步:

在刚才的程序上在修改main方法中的代码为:

同时创建两个对象然后再两个线程中运行我们会发现运行结果:

我们现在比较一下两个结果:

我们会发现在同步的时候,执行方式为执行A线程直到A线程完全执行完毕之后,再去执行B,原因是因为只有一个Has对象,资源存在竞争关系,当我们使用同步锁的时候就会受到同步机制的影响,当A线程占用了这个对象的资源的时候,其他线程就无法访问这个资源了,直到A执行完毕之后,释放了这个资源,这个时候B线程才有资格去拿到这个线程.我们把这个机制叫做同步.

那个第二个输出方式就和前一个不一样了,这种打印效果就是异步的.两个线程访问了两个不同的对象,这两个不同的对象产生了两个锁,所以一个线程中一个对象的锁并锁不住其他对象,所以就会这样输出.

结论:Java中synhronized关键字锁住的是一个对象,而不是一个方法或者一段代码.

=========================================

Java多线程学习笔记(三)同步和异步的更多相关文章

  1. Java多线程学习笔记(一)——多线程实现和安全问题

    1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...

  2. Java NIO 学习笔记(六)----异步文件通道 AsynchronousFileChannel

    目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...

  3. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

  4. JAVA多线程学习笔记(1)

    JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...

  5. Java多线程学习(三)volatile关键字

    转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...

  6. Java IO学习笔记三

    Java IO学习笔记三 在整个IO包中,实际上就是分为字节流和字符流,但是除了这两个流之外,还存在了一组字节流-字符流的转换类. OutputStreamWriter:是Writer的子类,将输出的 ...

  7. Java IO学习笔记三:MMAP与RandomAccessFile

    作者:Grey 原文地址:Java IO学习笔记三:MMAP与RandomAccessFile 关于RandomAccessFile 相较于前面提到的BufferedReader/Writer和Fil ...

  8. Java多线程学习笔记

    进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...

  9. JAVA WEB学习笔记(三):简单的基于Tomcat的Web页面

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  10. java多线程学习笔记(三)

    java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...

随机推荐

  1. 全网最详细的Git学习系列之介绍各个Git图形客户端(Windows、Linux、Mac系统皆适用ing)(图文详解)

    不多说,直接上干货! 一.TortoiseGit - The coolest Interface to Git Version Control TortoiseGit 是 TortoiseSVN 的  ...

  2. js关闭当前页面

    <a href="javascript:window.opener=null;window.open('','_self');window.close();">关闭&l ...

  3. struts2 ognl存放数据

    ongl存放数据可以存放在对象栈(root),也可以存放在map中 一.存放在map中 1.存放在map中可以分为存放在request.session.application public Strin ...

  4. Spring声明式事务为何不回滚

  5. Innosetup中在安装界面左下角添加超链接

    在程序的安装界面左下角加上超链接,如下图: 1. 新建一个标签,这里使用的控件是TNewStaticText ,完整的方法是 //该方法传入两个参数: //1. ParentForm:将这个URLLa ...

  6. java class load 类加载

    1:what is  it jvm把描述类的数据从class字节码文件加载到内存,并对数据进行校验.解析.初始化,最终成为jvm直接使用的数据类型 1.ClassNotFoundExcetpion  ...

  7. python实例:在列表,字典,集合中,根据条件筛选数据

    1. 从列表中过滤掉 负数 from random import randint # 随机生成列表 data = [randint(-10, 10) for _ in range(10)] print ...

  8. 如何在CentOS7上安装桌面环境?

    1.安装 GNOME-Desktop 安装GNOME桌面环境 # yum -y groups install "GNOME Desktop" 完成安装后,使用如下命令启动桌面 # ...

  9. CC2530串口工作

    前言 嘿嘿,我只是写给我自己的一篇博客,今天研究了一天的CC2530,感觉好累,虽然是已经落伍的技术了,但是我觉得不要小看它,还是能够学到点东西的,随着学习的深入,渐渐感觉有点突破的苗头了!哈哈 CC ...

  10. Timer控件

    Timer控件是定期引发事件的控件,时间间隔的长度由interval属性定义,其值以毫秒为单位吗,若启用了该组件,则每个事件间隔引发一个Tick事件,Timer组件的主要方法包括start和stop, ...