概述

关键字synchronized可以修饰方法或者以同步代码块的形式来进行使用,它主要确保多个线程在同一时刻只能有一个线程处于方法或者同步块中,它保证了线程对变量访问的可见性和排他性。

同步代码块
public class SynchronizedDemo implements Runnable {

    @Override
public void run() {
synchronized (this) {
System.out.println("当前线程:" + Thread.currentThread().getName());
try {
System.out.println("休眠2s");
Thread.sleep(2000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程:" + Thread.currentThread().getName() + "结束");
}
} public static void main(String[] args) {
SynchronizedDemo instance = new SynchronizedDemo();
Thread thread1 = new Thread(instance);
Thread thread2 = new Thread(instance);
thread1.start();
thread2.start(); }
}

运行结果:

同步代码块形式——锁为this,两个线程使用的锁是一样的,线程1必须要等到线程0释放了该锁后,才能执行。通过反编译分析Synchornized关键字作用在同步代码块时的实现原理,执行javap -v SynchronizedDemo.class,部分相关输出如下所示:

可以看到对于同步代码块,Synchronized使用了monitorenter和monitorexit指令。

同步方法
public class SynchronizedMethodDemo implements Runnable {

    @Override
public void run() {
method();
} // 修饰普通方法
public synchronized void method() {
System.out.println("当前线程:" + Thread.currentThread().getName());
try {
System.out.println("休眠2s");
Thread.sleep(2000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("当前线程:" + Thread.currentThread().getName() + "结束");
} public static void main(String[] args) {
SynchronizedDemo instance = new SynchronizedDemo();
Thread thread1 = new Thread(instance);
Thread thread2 = new Thread(instance);
thread1.start();
thread2.start();
}
}

输出结果

可以看到两个线程使用的锁是一样的,线程1必须要等到线程0释放了该锁后,才能执行。Synchronized作用在普通方法时锁对象默认为this。

执行反编译指令,查看输出结果:

同步方法依靠方法修饰符上的ACC_SYNCHRONIZED完成。

总结

Synchronized本质上是对一个对象的监视器(monitor)进行获取,而这个过程是排他的,也就是同一时刻只能有一个线程获取到Synchroniezd所保护对象的监视器。任何一个对象都有自己的监视器,当这个对象由同步块或者这个对象的同步方法调用时,执行方法的线程必须先获取到该对象的监视器才能进入同步块或者同步方法,而没有获取到监视器的线程将会被阻塞在同步块和同步方法的入口处,进入阻塞状态。

并发编程原理学习:synchronized关键字的更多相关文章

  1. 并发编程原理学习-reentrantlock源码分析

    ReentrantLock基本概念 ​ ReentrantLock是一个可重入锁,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁,并且在获取锁时支持选择公平模式或者非公平模式 ...

  2. Java并发编程之三:volatile关键字解析 转载

    目录: <Java并发编程之三:volatile关键字解析 转载> <Synchronized之一:基本使用>   volatile这个关键字可能很多朋友都听说过,或许也都用过 ...

  3. Atitit.并发编程原理与概论 attilax总结

    Atitit.并发编程原理与概论 attilax总结 1. 并发一般涉及如下几个方面:2 2. 线程安全性 ( 2.2 原子性 2.3 加锁机制2 2.1. 线程封闭3.3.1Ad-hoc线程封闭 3 ...

  4. Java并发编程原理与实战五:创建线程的多种方式

    一.继承Thread类 public class Demo1 extends Thread { public Demo1(String name) { super(name); } @Override ...

  5. 【java并发编程艺术学习】(三)第二章 java并发机制的底层实现原理 学习记录(一) volatile

    章节介绍 这一章节主要学习java并发机制的底层实现原理.主要学习volatile.synchronized和原子操作的实现原理.Java中的大部分容器和框架都依赖于此. Java代码 ==经过编译= ...

  6. Java并发编程原理与实战九:synchronized的原理与使用

    一.理论层面 内置锁与互斥锁 修饰普通方法.修饰静态方法.修饰代码块 package com.roocon.thread.t3; public class Sequence { private sta ...

  7. Java并发编程-深入探讨synchronized实现原理

    synchronized这个关键字对应Java程序猿来说是非常的熟悉,只要遇到要解决线程安全问题的地方都会使用这个关键字.接下来一起来探讨一下synchronized到底时怎么实现线程同步,使用syn ...

  8. Java并发编程深入学习

    上周的面试中,被问及了几个并发开发的问题,自己回答的都不是很系统和全面,可以说是"头皮发麻",哈哈.因此果断购入<Java并发编程的艺术>一书,该书内容主要是对ifev ...

  9. Java并发编程快速学习

    上周的面试中,被问及了几个关于Java并发编程的问题,自己回答的都不是很系统和全面,可以说是"头皮发麻",哈哈.因此果断购入<Java并发编程的艺术>一书,学习后的体会 ...

随机推荐

  1. c++对c的拓展_引用的基本用法

    实质:取别名 格式:原类型&别名=原变量名: 注意:1.定义时必须初始化 2.初始化后不能够改变指向 3.不可对Null进行引用 4.可对任意类型取别名包括数组(int (&别名)[个 ...

  2. Java重载容易引发的错误—返回类型

    方法的签名仅仅与方法名和参数类型相关,而与访问控制符.返回类型无关,以及方法体中的内容都没有关系,下面用一个例子说明; 如果Student类两种签名,myStudent(int,int)返回int 类 ...

  3. 使用SQL的FOR XML PATH('')将字段用逗号隔开

    FOR XML PATH('') 将查询结果显示为XML 经常用来将查询结果按逗号分隔后显示至某一字段 select * from Area结果 添加FOR XML PATH('')后 select ...

  4. C++的"开始" Hello World! 你好世界!

    # C++的"开始" Hello World! 你好世界! ```C++ // 第一个程序 //代表注释这一行 #include <iostream> //c++专属头 ...

  5. Java基础之浅谈泛型

    简单的介绍了Java泛型类型的使用.上手容易,深入很难.

  6. 讲解CPU之NUMA硬件体系以及机制(lscpu查看相关信息)

    先看看从系统层面反映出来的numa cpu信息.采样机器为实体机.80核.128内存. [root@ht2 src]# lscpu Architecture: x86_64 #x86架构下的64位 C ...

  7. 【Electron】Electron Icon 图标说明、及常见问题

    [Electron]Electron Icon 图标说明.及常见问题 其实各种打包模块都有相关的文档说明,相关链接如下: electron-builder:https://www.electron.b ...

  8. vue3组合式API

    vue3组合式API 为什么要用组合式API,我们来看看它是如何解决vue2的局限性的 1.vue2的局限性 当组件内容越来越多,逻辑越来越复杂,可读性就会降低,并且难以维护. vue2组件采用配置式 ...

  9. HCIE笔记-第五节-IP地址+VLSM

    192.168.1.111 -- 点分十进制 -- IPV4地址表示格式 计算机 只能识别 01010101 二进制 4组十进制数 规则:二进制0/1 在不同位表达的含义是不一致的,0永远代表不取值, ...

  10. vue学习day02

    vue 指令 1. 内容渲染指令 v-text 指令的缺点:会覆盖元素内部原有的内容! {{ }} 插值表达式:在实际开发中用的最多,只是内容的占位符,不会覆盖原有的内容! v-html 指令的作用: ...