Java synchronized解析
多线程三大特性:
可见性、原子性、有序性
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解析的更多相关文章
- java基础解析系列(五)---HashMap并发下的问题以及HashTable和CurrentHashMap的区别
java基础解析系列(五)---HashMap并发下的问题以及HashTable和CurrentHashMap的区别 目录 java基础解析系列(一)---String.StringBuffer.St ...
- java基础解析系列(一)---String、StringBuffer、StringBuilder
java基础解析系列(一)---String.StringBuffer.StringBuilder 前言:本系列的主题是平时容易疏忽的知识点,只有基础扎实,在编码的时候才能更注重规范和性能,在出现bu ...
- Java注解解析-搭建自己的注解处理器(CLASS注解使用篇)
该文章是继Java注解解析-基础+运行时注解(RUNTIME)之后,使用注解处理器处理CLASS注解的文章.通过完整的Demo例子介绍整个注解处理器的搭建流程以及注意事项,你将知道如何去搭建自己的注解 ...
- Java Synchronized Blocks
From http://tutorials.jenkov.com/java-concurrency/synchronized.html By Jakob Jenkov A Java synchro ...
- Java Sax解析
一. Java Sax解析是按照xml文件的顺序一步一步的来解析,在解析xml文件之前,我们要先了解xml文件的节点的种类,一种是ElementNode,一种是TextNode.如下面的这段boo ...
- Java XML解析工具 dom4j介绍及使用实例
Java XML解析工具 dom4j介绍及使用实例 dom4j介绍 dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory ...
- java synchronized(一)
java synchronized主要用于控制线程同步,中间有很多小的细节,知识,这里我简单的整理一下,做个记录.主要用于方法和代码块的控制 先说说方法控制 模拟银行存款和取款,创建一个Account ...
- java synchronized使用
java synchronized 基本上,所有并发的模式在解决线程冲突问题的时候,都是采用序列化共享资源的方案.这意味着在给定时刻只允许一个任务访问该资源.这个一般通过在代码上加一条锁语句实现,因为 ...
- Java泛型解析(03):虚拟机运行泛型代码
Java泛型解析(03):虚拟机运行泛型代码 Java虚拟机是不存在泛型类型对象的,全部的对象都属于普通类,甚至在泛型实现的早起版本号中,可以将使用泛型的程序编译为在1.0虚拟机上可以执行的 ...
随机推荐
- 一文搞懂 Linux network namespace
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 本文通过 IP ...
- Android--通知之Toast
前言 这篇博客讲解一下Android下的一个简单信息提示的方式:Toast.如果一直看我的博客,会发现在之前的Demo中,一直有用到Toast去提示消息,在这篇博客中就专门讲它.Toast提供一个浮动 ...
- 编写高质量代码改善java程序的151个建议——[1-3]基础?亦是基础
原创地址: http://www.cnblogs.com/Alandre/ (泥沙砖瓦浆木匠),需要转载的,保留下! Thanks The reasonable man adapts himse ...
- ZOJ Problem Set - 1730 Crazy Tea Party
#include<cstdio> int main(){ int T,n; scanf("%d",&T); while(T--){ scanf("%d ...
- github提交代码contributions不显示小绿块
问题描述: 最近发现一个问题就是不管是提交新增的代码还是修改后提交的代码在github的contributions上都不显示贡献小绿块. 于是我在 github help 里面找到了答案: 官方链接如 ...
- 11 使用Tensorboard显示图片
首先,下载一张png格式的图片(注意:只支持png格式),命名为1.png.然后,打开PythonShell,输入以下代码: import tensorflow as tf # 获取图片数据 file ...
- mysql列反转Pivoting
Pivoting是一项可以把行旋转为列的技术.在执行Pivoting的过程中可能会使用到聚合.Pivoting技术应用非常广泛.下面讨论的都是静态的Pivoting查询,即用户需要提前知道旋转的属性和 ...
- TensorFlow的图切割模块——Graph Partitioner
背景 [作者:DeepLearningStack,阿里巴巴算法工程师,开源TensorFlow Contributor] 在经过TensorFlow的Placer策略模块调整之后,下一步就是根据Pla ...
- Perl解除引用:从引用还原到数据对象
使用引用可以指向数据对象,这似乎很简单. @name1=qw(longshuai wugui); @name2=qw(xiaofang tuner); $ref_name=\@name1; push ...
- Markdown——入门使用
一 Markdown是什么 markdown是一种纯文本格式的标记语言.通过简单的标记语法,它可以使普通文本具有一定的格式.markdown的语法十分简单,常用的也不过十来个,是一种轻量级的标记语言, ...