Android实习面试准备——并发编程(一)

本文介绍了在单核CPU环境下多线程的必要性,详细对比了synchronized修饰普通方法和静态方法的区别,强调了可见性的重要性。同时,讨论了锁的分类,包括互斥锁、自旋锁、读写锁、乐观锁与悲观锁。还探讨了CAS无锁编程的原理以及ReentrantLock和AQS的实现机制,分析了公平锁与非公平锁的区别。
摘要由CSDN通过智能技术生成

1、假如只有一个cpu,单核,多线程还有用吗

        一般来说,一个任务既需要在CPU上花时间,也需要在IO上花时间,比如说读写文件等等。如果单核CPU、单线程的话,那么一个线程在处理的时候,CPU就是闲置的,这就浪费了CPU资源。而是多线程的话,一个CPU在等待IO的时候,另一个线程可以利用CPU进行计算,这样IO资源和CPU资源都得到了充分的利用。

2、sychronied修饰普通方法和静态方法的区别?什么是可见性

        sychronied修饰普通方法时,锁是对象锁。

        sychronied修饰静态方法时,锁是类锁,也就是类对应的class对象。每个类可以有不同的对象,但是class对象只有一个,所以如果不同的线程通过不同的对象调用方法不会造成线程阻塞,但是对于类锁而言,就算是不同的对象,多个线程调用该类的静态方法也会造成阻塞。

        可见性是指:多个线程访问同一个变量时,其中一个线程修改了这个变量的值,其它线程能够立即看到修改值。volatile可以保证可见性,它会保证修改的值会立即更新到主存,所以对其它线程是可见的。而普通的共享变量不能保证可见性,因为被修改后放在线程的工作内存里,何时更新到主存不确定,所以其它线程读取的时候可能得到的是未修改的值。

3、锁分哪几类

(1)互斥锁和自旋锁

        最基本的两种锁。互斥锁和自旋锁对于加锁失败之后的处理不一样。互斥锁加锁失败后,线程会释放CPU,给其他线程。自旋锁加锁失败后,线程会忙等待,直到它拿到锁。

(2)读写锁

        读写锁适用于能明确区分读操作和写操作的场景。写锁是独占锁,因为任意时刻只能有一个线程持有写锁,而读锁是共享锁,多个线程可以同时持有。读写锁可以根据应用场景选择互斥锁和自旋锁的一种来实现。

(3)乐观锁与悲观锁

        前面的互斥锁、自旋锁和读写锁都是悲观锁,悲观锁认为多线程同时修改共享资源的概率较高,很容易出现冲突,所以访问共享资源前就要上锁。乐观锁假定冲突的概率较低,所以她的工作方式是:先修改完共享资源,再验证这段时间有没有发生冲突,如果没有其它线程在修改资源,那么操作完成;如果发现有其它线程在修改,这次操作无效。

4、CAS无锁编程的原理

        CAS即compare and swap(比较与交换),无锁编程也就是在不使用锁的情况下实现多线程之间的变量同步,其涉及到三个操作数:需要读写的内存值,预期值A,准备写入的新值B。工作原理是首先读取内存里的值V,和A进行比较,如果V=A,则将V更新为B,如果不相等,则操作就失败,进入自旋等待状态。

        CAS是一种系统原语,是操作系统硬件提供的功能,也就是说比较与交换是一种原子操作,comapre成功了,swap也就成功了。

5、ReentrantLock和AQS实现原理

         首先是ReentrantLock、AQS等几个关键类的关系。然后从ReentrantLock.lock()来分析ReentrantLock和AQS的原理,ReentrantLock.lock()的调用关系如下图:

         先来看看最终的acquire方法,也就是

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值