多线程三大特性:

可见性、原子性、有序性

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. java中根据key获取resource下properties资源文件中对应的参数

    properties资源文件是放在resource目录下的: 新建工具类: package com.demo.utils; import java.io.InputStream; import jav ...

  2. PHP之ThinkPHP框架(数据库)

    PHP是网站后台开发语言,其重要的操作对象莫过于数据库,之前有了解过mysqli和pdo,但ThinkPHP的数据库交互必须使用其特定的封装方法,或者可以认为其是对PHP数据库操作的进一步封装,以达到 ...

  3. 使用Docker发布DNC项目

    项目结构 可以忽略中间三个Console项目 ApiCenter 是一个WebAPI项目,引用了NLog.MQ项目 ApiCenter使用5001端口 public static IWebHost B ...

  4. 移动设备(手机)的唯一ID有哪些

    移动设备(手机)的唯一ID有哪些 在移动广告领域,设备的ID 是用来追踪一个人的最重要的标识. 对于APP自身产品而言,使用设备唯一ID可以追踪到用户从下载到激活.注册.使用.流失.回归的全流程数据, ...

  5. salesforce lightning零基础学习(十一) Aura框架下APP构造实现

    前面的一些lightning文章讲述了aura的基础知识,aura封装的常用js以及aura下的事件处理.本篇通过官方的一个superbadge来实现一个single APP的实现. superbad ...

  6. ⑤早起的鸟儿有虫吃-JSTL核心标签库[收藏]

    介绍 JSTL 全名为Java Server Pages Standard Tag Library(JSP Standard Tag Library),它的中文名称为JSP 标准标签函数库. Web  ...

  7. ②萨克斯,音符的悠扬(Session管理)

    一.前言 小朽不才,最近喜欢上了萨克斯,一年计划[传送门]中的实行.就伴随着一首萨克斯,整理了下Session管理和Session四种技术. 保存状态: #网址重写(URL rewriting) #隐 ...

  8. 用js如何获取file是否存在

    其实注意点就可以知道了. 举个例子 firebug看出这代码: <div id="SWFUpload_0_0" class="uploadify-queue-ite ...

  9. PowerDesigner使用方法

    我们需要创建一个测试数据库,一步一步来学习使用PowerDesigner,为了简单,我们在这个数据库中只创建一个Student表和一个Major表.其表结构和关系如下所示. 看看怎样用PowerDes ...

  10. 彻底弄懂 Unicode 编码

    彻底弄懂 Unicode 编码 今天,在学习 Node.js 中的 Buffer 对象时,注意到它的 alloc 和 from 方法会默认用 UTF-8 编码,在数组中每位对应 1 字节的十六进制数. ...