1 线程不安全演示

public class ThreadAndLockTest1 {
private static int a = 0;
public static void main(String[] args) throws InterruptedException {
CountDownLatch la = new CountDownLatch(2);
for (int t = 0;t < 2;t++){
new Thread(()->{
for (int i = 0;i < 100000;i++) {
a++;
}
la.countDown();
}).start();
}
la.await();
System.out.println(a);
}
}

如果线程安全,那么打印结果应该是200000

执行结果,发现不是期望的结果,说明线程不安全

149202

2 锁演示

上面代码加上锁(synchronized)之后

public class ThreadAndLockTest1 {
private static int a = 0;
public static void main(String[] args) throws InterruptedException {
CountDownLatch la = new CountDownLatch(2);
for (int t = 0;t < 2;t++){
new Thread(()->{
synchronized (ThreadAndLockTest1.class){
for (int i = 0;i < 100000;i++) {
a++;
}
}
la.countDown();
}).start();
}
la.await();
System.out.println(a);
}
}

执行结果,是期望的结果

200000

3 对象在内存里面的存储布局(Oracle的虚拟机)

  什么东西可以作为一把锁?在解释这个问题之前,先了解对象是由什么构成的?

3.1 它主要分为三个部分

对象头:对象头又包括两类:markword,class pointer,

实例数据:instance data,

对齐填充:padding

3.2 markword

  它的大小是8字节

1)哈希码、

2)GC年龄分代、

3)锁的信息

  锁状态标志

  线程持有的锁、

  偏向线程id

  偏向时间戳

3.3 使用JOL查看对象内存

https://www.cnblogs.com/jthr/p/15980849.html

4 查看上锁对象在内存中布局

上面我们知道了对象的组成和怎么去看对象中的布局,现在我们来看下对象在上锁前、上锁中、上锁后的变化

4.1 示例代码

public class JolTest {

    static class T{
} public static void main(String[] args) {
T o = new T();
System.out.println(ClassLayout.parseInstance(o).toPrintable());
synchronized (o){
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
System.out.println(ClassLayout.parseInstance(o).toPrintable());
}
}

4.2 执行结果

发现上锁后对象头中的markword发生的变化,解锁后又恢复了。

上锁实际上是在对象头上做了个标记

001代表无锁

00代表轻量级锁

  

线程基础知识 03 synchronized锁(对象在内存的布局和加上锁后对象在内存中的变化)的更多相关文章

  1. Java并发编程(一):线程基础知识以及synchronized关键字

    1.线程与多线程的概念:在一个程序中,能够独立运行的程序片段叫作“线程”(Thread).多线程(multithreading)是指从软件或者硬件上实现多个线程并发执行的技术. 2.多线程的意义:多线 ...

  2. java线程基础知识----线程与锁

    我们上一章已经谈到java线程的基础知识,我们学习了Thread的基础知识,今天我们开始学习java线程和锁. 1. 首先我们应该了解一下Object类的一些性质以其方法,首先我们知道Object类的 ...

  3. 《Java基础知识》Java锁详解(volatile,synchronized等)

    volatile: 让变量每次在使用的时候,都从主存中取. volatile具有synchronized关键字的“可见性”,但是没有synchronized关键字的“并发正确性”,也就是说不保证线程执 ...

  4. Java线程基础知识(状态、共享与协作)

    1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源 ...

  5. java线程基础知识----线程基础知识

    不知道从什么时候开始,学习知识变成了一个短期记忆的过程,总是容易忘记自己当初学懂的知识(fuck!),不知道是自己没有经常使用还是当初理解的不够深入.今天准备再对java的线程进行一下系统的学习,希望 ...

  6. java多线程中篇(二) —— 线程的创建和Synchronized锁关键字

    学习之前,先了解线程状态图 说明:线程共包括以下5种状态. 1. 新建状态(New)         : 线程对象被创建后,就进入了新建状态.例如,Thread thread = new Thread ...

  7. Java 线程基础知识

    前言 什么是线程?线程,有时被称为轻量进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程 ID,当前指令指针 (PC),寄存器集合和堆栈组成.另外,线 ...

  8. Java并发之线程管理(线程基础知识)

    因为书中涵盖的知识点比较全,所以就以书中的目录来学习和记录.当然,学习书中知识的时候自己的思考和实践是最重要的.说到线程,脑子里大概知道是个什么东西,但很多东西都还是懵懵懂懂,这是最可怕的.所以想着细 ...

  9. Java__线程---基础知识全面实战---坦克大战系列为例

    今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的jav ...

  10. Java并发(基础知识)——显示锁和同步工具类

    显示锁                                                                                     Lock接口是Java ...

随机推荐

  1. Paddle Graph Learning (PGL)图学习之图游走类模型[系列四]

    Paddle Graph Learning (PGL)图学习之图游走类模型[系列四] 更多详情参考:Paddle Graph Learning 图学习之图游走类模型[系列四] https://aist ...

  2. Go语言核心36讲45

    你好,我是郝林,我今天继续分享bufio包中的数据类型. 在上一篇文章中,我提到了bufio包中的数据类型主要有Reader.Scanner.Writer和ReadWriter.并着重讲到了bufio ...

  3. Codeforces Round #835 (Div. 4) A-G

    比赛链接 A 题意 给出三个不同的数,求中位数. 题解 知识点:模拟. 显然. 时间复杂度 \(O(1)\) 空间复杂度 \(O(1)\) 代码 #include <bits/stdc++.h& ...

  4. 痞子衡嵌入式:MCUXpresso IDE下高度灵活的FreeMarker链接文件模板机制

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是MCUXpresso IDE下高度灵活的FreeMarker链接文件模板机制. 痞子衡之前写过一篇文章 <MCUXpresso I ...

  5. 产生10个1-20以内的随机数,要求不能重复(集合)Java

    public class Demo{ //产生10个1-20以内的随机数,要求不能重复 public static void main(String[] args){ //新建集合存放随机数 Set& ...

  6. 【每日一题】【递归实现、自下而上、优化】-2022年1月12日-NC68 跳台阶

    描述一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个 n 级的台阶总共有多少种跳法(先后次序不同算不同的结果). 数据范围:0 \leq n \leq 400≤n≤40要求:时间复杂度: ...

  7. 记录一次缓存引起的线上BUG

    背景 有一个需求大概是这样的,为了提高推荐系统的性能,需要本来从A服务获取的帖子信息,改为从Redis里面重新读取 Redis里面没有存帖子的所有信息,只存储了推荐系统必要的字段 大概是这样的: 至于 ...

  8. Django框架路由层-无名有名分组-无名有名分组反向解析

    目录 一:路由层 1.路由匹配(错误演示) 2.路由匹配错误原因 3.路由匹配(解决方式1) 4.settings配置文件控制自动添加斜杠匹配 5.url方法第一个参数是正则表达式(正规使用url) ...

  9. JavaScript中的防抖与节流-图文版

    01.防抖还是节流 防抖 与 节流 目的都是避免一定时间内,大量重复的操作造成的性能损耗.因此原理也类似,都是阻止过多的事件执行,只保留一部分来执行.适用场景略有不同,也有交叉,动手练习一遍就懂了. ...

  10. Clickhouse表引擎探究-ReplacingMergeTree

    作者:耿宏宇 1 表引擎简述 1.1 官方描述 MergeTree 系列的引擎被设计用于插入极大量的数据到一张表当中.数据可以以数据片段的形式一个接着一个的快速写入,数据片段在后台按照一定的规则进行合 ...