首先是一段代码:

 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. python 网络编程之socket开发和socketserver模块

    一 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网中处处是C/S架构 如黄色网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种) 腾讯作为服务端为你提供视频 ...

  2. Linux快速查看某条命令的版本和存放的位置(ls -l `which mvn`)

    输入: ls -l `which mvn` 如图:

  3. 把TextView中的文字添加阴影效果及Style的使用 mono版

    android:shadowColor 阴影颜色 android:shadowDx 阴影的水平偏移量 android:shadowDy 阴影的垂直偏移量 android:shadowRadius 阴影 ...

  4. 数学还勉强管用,用代码还能画个canvas 仪表盘(含完整代码)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. [Xamarin.Android] 儲存資料於Windows Azure (转帖)

    在準備討論Xamarin.Android 如何整合GCM與Windows Azure來實作Push Notification之前, 先來了解如何將Xamarin.Android 與Windows Az ...

  6. (转)生活中的OO智慧——大话面向对象五大原则

    一·单一职责原则(Single-Responsibility Principle) 定义:一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中. 宿舍里并不能好好学习,自习还是得去图书馆.这 ...

  7. IO流(二)字符流

    1.字符流:在字节流的基础上添加了编码机制.很大程度上和字节流操作一样的,字符流只能操作文本类文件,准确的说应该是纯文本类文件.例如.txt,.java,.cpp,.html等 编码:每一个国家都有自 ...

  8. mac环境下使用docker安装nginx

    前言 距离上一篇文章已经很长时间,近期实在事情太多了,也没来得及继续更新一些新的内容.现在开发使用的工作实在太多了,小编实在忍受不了windows那样卡机的状态,于是最近换了一个mac电脑,虽然做开发 ...

  9. EF那点事

    EntityFramework 1-->什么是EnitityFramework   1.1--> ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出 ...

  10. 学会了ES6,就不会写出那样的代码

    用let不用var ES6之前我们用var声明一个变量,但是它有很多弊病: 因为没有块级作用域,很容易声明全局变量 变量提升 可以重复声明 还记得这道面试题吗? var a = []; for (va ...