高级程序员面试题库,多线程总结-底层原理(1),2024年我们程序员该如何进阶和规划

public static void writer() {
obj = new FinalExample();
}

public static void reader() {
FinalExample object = obj;
int a = object.i;
int b = object.j;
}
}

在前面有介绍,对于语句obj = new FinalExample();其实对应有三个步骤:

  1. 分配内存空间
  2. 初始化对象
  3. 将内存空间的地址赋给对应的引用

CPU在执行时的指令重排,可能会导致第2个步骤在第3个步骤之后执行。对于以上代码就是返回的obj是一个还没有初始化好的对象。虽然构造函数执行了,但是其属性还未初始化完成,所以此时如果有一个线程B来调用其reader方法,拿到的属性便是错误的数据。而final关键字会禁止CPU的这一行为,保证其初始化在构造函数返回之前执行。

synchronized

synchronized关键字可以作用于普通方法,静态方法, 代码块,运行时会对相应的位子进行加锁。

  • 对于普通方法,锁是当前实例, 所以只有同一个实例调用该方法才会互斥
  • 对于静态方法,锁是当前类的Class对象,类级别的锁。即使在不同的线程中调用不同实例对象,也会有互斥效果
  • 对于同步代码块,锁是sychronized括号里配置的对象

普通方法/静态方法

我们定义一个类如下:

package com.fred.javalib.thread;

public class EmptyClass {
public synchronized void syncMethod() {
}

public synchronized static void syncStaticMethod() {
}
}

查看其字节码文件

image.png 可以发现, 被sychronized修饰的方法在被编译后,其方法的flags属性中会多一个ACC_SYNCHRONIZED标识。当虚拟机在访问有这个标识的方法时,会在相应的位置添加monitorentermonitorexit指令

同步代码块

对于同步代码块, 是靠monitorenter, monitorexit指令来实现,我们用javap -verbose Singleton.class来看一下上面用volatile关键字实现的单例模式相关代码。

image.png 可以看到在上面的字节码中,有一个monitorenter 和 2个monitorexit。有monitorenter是去拿锁, 有两个monitorexit是因为其中一个是代码正常执行结束后释放锁,一个是在代码执行异常时释放锁。

happens-before规则

保证线和可见性的机制,前面一个操作的结果对后续操作是可见的。

1. 程序的顺序性原则

在一个线程中,按照程序顺序,前面的操作happens-before于后续的任意操作。

2. volatile变量规则

对于一个volatile变量的写操作, happens-before于后续对这个volatile变量的读操作。

3. 传递性

如果A happens-before B,且 B happens-before C,那么 A happens-before C。

4. 锁的规则

对于一个锁的解锁Happens-Before于后续对这个锁的加锁。

5. 线程start()规则

它是指主线程 A 启动子线程 B 后,子线程 B 能够看到主线程在启动子线程 B 前的操作。

6. 线程join()规则

主线程A等待子线程B完成(主线程 A 通过调用子线程 B 的 join() 方法实现), 当子线程B完成后(主线程A中的join方法返回) 主线程能看到子线程的操作。所谓的“看到”,指的是对共享变量的操作。

操作系统层面提供的两种同步的方法

信号量与管程都是操作系统提供的两种同步的方法。多线程的并发导致资源竞争。同步就是协调多线程对共享数据的访问,任何时刻只能有一个线程访问。

信号量

信号量(semaphore) 是操作系统提供的协调共享资源访问的方法。软件同步是平等线程间的一种同步协商机制,信号量是由OS来进行管理的。信号量用来表示系统的一类资源,信号量的取值就是一类资源数。由Dijkstra在20世纪60年代提出, 是早期的操作系统里的主要同步机制,但现在很少用。 信号量是一种抽象的数据类型:

  • 由一个整型变量(sem)和两个原子操作组成
  • P()操作(荷兰语尝试减少)
  • sem 减 1
  • 如sem < 0, 进入等待,否则继续
  • V()
  • sem 加 1
  • 如sem <=0, 唤醒一个等待进程

信号量是被保护的整型变量,初始化完成后,只能通过P和V操作修改,由操作系统保证,PV操作都是原子操作

  • P可能阻塞,V不会阻塞(V操作只会释放资源, 不可能阻塞)
  • 通常假定信号量是公平的,结程不会被无限期阻塞在P操作里,假定信号量等待按先进先出排队。
信号量实现临界区的资源访问

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上我搜集整理的2019-2021BATJ 面试真题解析,我把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节。

节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

《960全网最全Android开发笔记》

《379页Android开发面试宝典》

历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

如何使用它?

1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

腾讯、字节跳动、阿里、百度等BAT大厂 2019-2021面试真题解析

资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算**

  • 20
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值