多线程三大特性:

可见性、原子性、有序性

synchronize的特性:

1、同一时刻只有一个线程访问临界资源

2、其它未获取到锁执行权的线程必须排队等待

3、保证共享资源的原子性、可见性和有序性

4、进入synchronized范围内自动加锁,synchronized作用域外锁自动消除,即使异常也会释放锁

synchronize加锁的方式:

  • 对于普通同步方法,锁是当前实例对象。

  • 对于静态同步方法,锁是当前类的Class对象。

  • 对于同步方法块,锁是Synchonized括号里配置的对象。

通过具体的例子来看一下

首先是普通方法:

 class NoSyncTest {
public void method1() {
Log.i("sync", "method 1 start");
try {
Log.i("sync", "method 1 execute");
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("sync", "method 1 end");
} public void method2() {
Log.i("sync", "method 2 start");
try {
Log.i("sync", "method 2 execute");
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("sync", "method 2 end");
}
} private void noSyncTest() {
final NoSyncTest test = new NoSyncTest(); Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
test.method1();
}
}); Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
test.method2();
}
}); thread1.start();
thread2.start();
}

这是一个没有任何同步的方法,NoSyncTest这个类有两个方法method1和method2,分别执行睡3s和0.5s的动作,然后再两个线程中分别调用这个类的实例test的两个方法,看一下结果:

可以看到method2和method1同时执行,method2因为sleep的时间短所以先结束。

再看一下普通方法同步:

class MethodSyncTest {
public synchronized void method1() {
Log.i("sync", "method 1 start");
try {
Log.i("sync", "method 1 execute");
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("sync", "method 1 end");
} public synchronized void method2() {
Log.i("sync", "method 2 start");
try {
Log.i("sync", "method 2 execute");
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("sync", "method 2 end");
}
} private void MethodSyncTest() {
final MethodSyncTest test = new MethodSyncTest(); Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
test.method1();
}
}); Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
test.method2();
}
}); thread1.start();
thread2.start();

synchronize修饰的method1和method2,其他不变,看一下结果:

method1先执行然后3s之后结束了method2才开始执行。(注意这个地方不能new 不同的对象来调用方法,因为修饰普通方法本质是对对象的同步加锁。)

看一下第三种静态同步方法:

 static class StaticMethodSyncTest {
public static synchronized void method1() {
Log.i("sync", "method 1 start");
try {
Log.i("sync", "method 1 execute");
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("sync", "method 1 end");
} public static synchronized void method2() {
Log.i("sync", "method 2 start");
try {
Log.i("sync", "method 2 execute");
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("sync", "method 2 end");
}
public static synchronized void method3() {
Log.i("sync", "method 3 start");
try {
Log.i("sync", "method 3 execute");
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("sync", "method 3 end");
}
} private void StaticMethodSyncTest() {
final StaticMethodSyncTest test1 = new StaticMethodSyncTest();
final StaticMethodSyncTest test2 = new StaticMethodSyncTest(); Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
test1.method1();
}
}); Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
test2.method2();
}
});
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
StaticMethodSyncTest.method3();
}
}); thread1.start();
thread2.start();
thread3.start();
}

static修饰方法相当于这个方法是类方法,可以直接通过类名.方法名调用。我们在这new出了test1和test2两个对象分别调用method1和method2,以及通过类名.方法名调用method3,看一下结果

method1、method2、method3顺序执行。(同步静态方法的本质是锁的当前类)

Java synchronized解析的更多相关文章

  1. java基础解析系列(五)---HashMap并发下的问题以及HashTable和CurrentHashMap的区别

    java基础解析系列(五)---HashMap并发下的问题以及HashTable和CurrentHashMap的区别 目录 java基础解析系列(一)---String.StringBuffer.St ...

  2. java基础解析系列(一)---String、StringBuffer、StringBuilder

    java基础解析系列(一)---String.StringBuffer.StringBuilder 前言:本系列的主题是平时容易疏忽的知识点,只有基础扎实,在编码的时候才能更注重规范和性能,在出现bu ...

  3. Java注解解析-搭建自己的注解处理器(CLASS注解使用篇)

    该文章是继Java注解解析-基础+运行时注解(RUNTIME)之后,使用注解处理器处理CLASS注解的文章.通过完整的Demo例子介绍整个注解处理器的搭建流程以及注意事项,你将知道如何去搭建自己的注解 ...

  4. Java Synchronized Blocks

    From http://tutorials.jenkov.com/java-concurrency/synchronized.html By Jakob Jenkov   A Java synchro ...

  5. Java Sax解析

    一.   Java Sax解析是按照xml文件的顺序一步一步的来解析,在解析xml文件之前,我们要先了解xml文件的节点的种类,一种是ElementNode,一种是TextNode.如下面的这段boo ...

  6. Java XML解析工具 dom4j介绍及使用实例

    Java XML解析工具 dom4j介绍及使用实例 dom4j介绍 dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory ...

  7. java synchronized(一)

    java synchronized主要用于控制线程同步,中间有很多小的细节,知识,这里我简单的整理一下,做个记录.主要用于方法和代码块的控制 先说说方法控制 模拟银行存款和取款,创建一个Account ...

  8. java synchronized使用

    java synchronized 基本上,所有并发的模式在解决线程冲突问题的时候,都是采用序列化共享资源的方案.这意味着在给定时刻只允许一个任务访问该资源.这个一般通过在代码上加一条锁语句实现,因为 ...

  9. Java泛型解析(03):虚拟机运行泛型代码

    Java泛型解析(03):虚拟机运行泛型代码      Java虚拟机是不存在泛型类型对象的,全部的对象都属于普通类,甚至在泛型实现的早起版本号中,可以将使用泛型的程序编译为在1.0虚拟机上可以执行的 ...

随机推荐

  1. 【app】自动化环境搭建(Appium)for java

    Appium来做app自动化相信大家都很熟悉了吧,就不再赘述他的概念和作用了,我们接下来着重介绍怎么来搭建整个app自动化环境,整个环境包括如下几个步骤: 1.安装jdk和eclipse及配置jdk的 ...

  2. 使用 SonarQube 来分析 .NET Core 项目代码问题

    0.介绍 Sonar 是一款开源的代码分析工具,可能有很多人已经用过,本篇文章主要是讲解如何在 Docker 里面安装 Sonar 并且用其来分析 .Net Core 项目. Sonar 是一个用于代 ...

  3. supervisor 启动dotnet.core 报“ too many start retries too quickly”

    环境: 操作系统:Centos 7 dotnet core:2.0.0    2.1.3 问题: 在使用supervisor 配置守护进程时,启动dotnet.core程序失败,查看/tmp下supe ...

  4. rest-framework之解析器

    解析器 解析器的作用 根据请求头 content-type 选择对应的解析器对请求体内容进行处理. 有application/json,x-www-form-urlencoded,form-data等 ...

  5. 《JavaScript总结》js的运行机制

    首先大家都知道javascript是单线程语言. 什么是单线程呢?比如我们去车站买票,只有一个售票窗口,大家排队买票,需要前面的人买完票,后面的人才能买票. 那为什么javascript不能是多线程呢 ...

  6. Nginx 配置https 服务

    一.HTTPS 服务 为什么需要HTTPS? 原因:HTTP不安全 1.传输数据被中间人盗用.信息泄露 2.数据内容劫持.篡改 HTTPS协议的实现 对传输内容进行加密以及身份验证 HTTPS加密校验 ...

  7. MySQL数据库——表操作

    I.表操作 一.创建表 基本语法如下: create table 表名( 列名 类型 是否可以为空, 列名 类型 是否可以为空 )ENGINE=InnoDB DEFAULT CHARSET=utf8: ...

  8. 修改wampsever中MySql5.7.14默认为空的密码

    ①打开WAMP找中MySql控制台,提示输入密码,开始密码为空,直接按回车 ②输入[use mysql],控制台提示[Database changed] ③输入[update user set aut ...

  9. More Effective C# 【前戏】

    买了很多很多书,想到就买,觉得有需要就买.买书的情况是不一样的:有时候,买的时候还是比较空,买来之后工作开始忙起来了,就没怎么看:有时候,买的时候比较忙,忙的乱了方寸,觉得有必要找本书来静心一下.不过 ...

  10. 翻译:如何向MariaDB中快速插入数据(已提交到MariaDB官方手册)

    本文为mariadb官方手册:How to Quickly Insert Data Into MariaDB的译文. 原文:https://mariadb.com/kb/en/how-to-quick ...