多线程三大特性:

可见性、原子性、有序性

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. List,泛型和Datatable 的相互转换

    public static DataTable ToDataTableTow(IList list) { DataTable result = new DataTable(); ) { Propert ...

  2. Centos7单机部署ELK+x-pack

    ELK分布式框架作为现在大数据时代分析日志的常为大家使用.现在我们就记录下单机Centos7部署ELK的过程和遇到的问题. 系统要求:Centos7(内核3.5及以上,2核4G) elk版本:6.2. ...

  3. js变量提升与函数提升的详细过程

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  4. Spring Cloud Gateway中异常处理

    最近我们的项目在考虑使用Gateway,考虑使用Spring Cloud Gateway,发现网关的异常处理和spring boot 单体应用异常处理还是有很大区别的.让我们来回顾一下异常. 关于异常 ...

  5. nginx部署django应用

    Django部署方式有很多种,之前写过一篇部署在Apache上的博文:https://www.cnblogs.com/shenh/p/7552722.html .下文介绍的是通过Nginx来部署. N ...

  6. 【leet-code】135. 加油站

    题目描述 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升. 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升.你从其 ...

  7. Hyperledger Fabric链码之三

    在<Hyperledger Fabric链码之一>和<Hyperledger Fabric链码之二>中我们介绍了链码的定义,并通过dev网络测试了测试了自己编写的链码程序. 本 ...

  8. C 程序与 C++ 程序之间的相互调用

    因为 C 编译器编译函数时不带参数的类型信息,只包含函数的符号名字.如 void foo( int x ) , C 编译器会将此函数编译成类似 _foo 的符号,C 链接器只要找到了调用函数的符号,就 ...

  9. Spring Boot入门(13)自制音乐平台

      经过笔者这几天的辛勤劳作(其实就是苦逼地码代码),一个新的网站已经上线啦!该网站是用Spring Boot工具写的,主要实现的功能如下: 根据歌曲名称和音乐平台搜索歌曲,并实现歌曲的在线播放: 歌 ...

  10. 【转】AJAX中JSON数据的返回处理问题

    AJAX处理复杂数据时,便会使用JSON格式.常用在对数据库的数据查询上.在数据库查询到数据后,便可在处理页面直接将数据转为JSON格式,然后返回. 本篇主要讨论:jQuery中,JSON数据在AJA ...