Java多线程学习笔记(三)同步和异步
首先是一段代码:
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多线程学习笔记(三)同步和异步的更多相关文章
- Java多线程学习笔记(一)——多线程实现和安全问题
1. 线程.进程.多线程: 进程是正在执行的程序,线程是进程中的代码执行,多线程就是在一个进程中有多个线程同时执行不同的任务,就像QQ,既可以开视频,又可以同时打字聊天. 2.线程的特点: 1.运行任 ...
- Java NIO 学习笔记(六)----异步文件通道 AsynchronousFileChannel
目录: Java NIO 学习笔记(一)----概述,Channel/Buffer Java NIO 学习笔记(二)----聚集和分散,通道到通道 Java NIO 学习笔记(三)----Select ...
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- JAVA多线程学习笔记(1)
JAVA多线程学习笔记(1) 由于笔者使用markdown格式书写,后续copy到blog可能存在格式不美观的问题,本文的.mk文件已经上传到个人的github,会进行同步更新.github传送门 一 ...
- Java多线程学习(三)volatile关键字
转载请备注地址:https://blog.csdn.net/qq_34337272/article/details/79680693 系列文章传送门: Java多线程学习(一)Java多线程入门 Ja ...
- Java IO学习笔记三
Java IO学习笔记三 在整个IO包中,实际上就是分为字节流和字符流,但是除了这两个流之外,还存在了一组字节流-字符流的转换类. OutputStreamWriter:是Writer的子类,将输出的 ...
- Java IO学习笔记三:MMAP与RandomAccessFile
作者:Grey 原文地址:Java IO学习笔记三:MMAP与RandomAccessFile 关于RandomAccessFile 相较于前面提到的BufferedReader/Writer和Fil ...
- Java多线程学习笔记
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间.(只负责空间分配) 线程:进程中的一个执行单元,负责进程汇总的程序的运行,一个进程当中至少要有一个线程. 多线程:一个进程中时可以有多个线 ...
- JAVA WEB学习笔记(三):简单的基于Tomcat的Web页面
注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...
- java多线程学习笔记(三)
java多线程下的对象及变量的并发访问 上一节讲到,并发访问的时候,因为是多线程,变量如果不加锁的话,会出现“脏读”的现象,这个时候需要“临界区”的出现去解决多线程的安全的并发访问.(这个“脏读”的现 ...
随机推荐
- 全网最详细的Git学习系列之介绍各个Git图形客户端(Windows、Linux、Mac系统皆适用ing)(图文详解)
不多说,直接上干货! 一.TortoiseGit - The coolest Interface to Git Version Control TortoiseGit 是 TortoiseSVN 的 ...
- js关闭当前页面
<a href="javascript:window.opener=null;window.open('','_self');window.close();">关闭&l ...
- struts2 ognl存放数据
ongl存放数据可以存放在对象栈(root),也可以存放在map中 一.存放在map中 1.存放在map中可以分为存放在request.session.application public Strin ...
- Spring声明式事务为何不回滚
- Innosetup中在安装界面左下角添加超链接
在程序的安装界面左下角加上超链接,如下图: 1. 新建一个标签,这里使用的控件是TNewStaticText ,完整的方法是 //该方法传入两个参数: //1. ParentForm:将这个URLLa ...
- java class load 类加载
1:what is it jvm把描述类的数据从class字节码文件加载到内存,并对数据进行校验.解析.初始化,最终成为jvm直接使用的数据类型 1.ClassNotFoundExcetpion ...
- python实例:在列表,字典,集合中,根据条件筛选数据
1. 从列表中过滤掉 负数 from random import randint # 随机生成列表 data = [randint(-10, 10) for _ in range(10)] print ...
- 如何在CentOS7上安装桌面环境?
1.安装 GNOME-Desktop 安装GNOME桌面环境 # yum -y groups install "GNOME Desktop" 完成安装后,使用如下命令启动桌面 # ...
- CC2530串口工作
前言 嘿嘿,我只是写给我自己的一篇博客,今天研究了一天的CC2530,感觉好累,虽然是已经落伍的技术了,但是我觉得不要小看它,还是能够学到点东西的,随着学习的深入,渐渐感觉有点突破的苗头了!哈哈 CC ...
- Timer控件
Timer控件是定期引发事件的控件,时间间隔的长度由interval属性定义,其值以毫秒为单位吗,若启用了该组件,则每个事件间隔引发一个Tick事件,Timer组件的主要方法包括start和stop, ...