1 ) 使用标志位
2)使用stop()
方法,但该方法就像关掉电脑电源一样,可能会发生预料不到的问题
3)使用中断interrupt()
public class Thread {
// 中断当前线程
public void interrupt();
// 判断当前线程是否被中断
public boolen isInterrupt();
// 清除当前线程的中断状态,并返回之前的值
public static boolen interrupted();
}
但调用interrupt()
方法只是传递中断请求消息,并不代表要立马停止目标线程。
8、讲一下java中的同步的方法
之所以需要同步,因为在多线程并发控制,当多个线程同时操作一个可共享的资源时,如果没有采取同步机制,将会导致数据不准确,因此需要加入同步锁,确保在该线程没有完成操作前被其他线程调用,从而保证该变量的唯一一性和准确性。
1) synchronized修饰同步代码块或方法
由于java的每个对象都有一个内置锁,用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需获得内置锁,否则就处于阴塞状态。
2) volatile修饰变量
保证变量在线程间的可见性,每次线程要访问volatile修饰的变量时都从内存中读取,而不缓存中,这样每个线程访问到的变量都是一样的。且使用内存屏障。
3) ReentrantLock重入锁,它常用的方法有ReentrantLock()
:创建一个ReentrantLock实例lock()
获得锁 unlock()
释放锁
4) 使用局部变量ThreadLocal实现线程同步,每个线程都会保存一份该变量的副本,副本之间相互独立,这样每个线程都可以随意修改自己的副本,而不影响其他线程。
常用方法ThreadLocal()
创建一个线程本地变量;get()
返回此线程局部的当前线程副本变量;initialValue()
返回此线程局部变量的当前线程的初始值;set(Tvalue)
将此线程变量的当前线程副本中的值设置为value
5) 使用原子变量,如AtomicInteger
,常用方法AtomicInteger(int value)
创建个有给定初始值的AtomicInteger
整数;addAndGet(int data)
以原子方式将给定值与当前值相加
6) 使用阻塞队列实现线程同步LinkedBlockingQueue<E>
9、如何保证线程安全?
线程安全性体现在三方法:
1)原子性: 提供互斥访问,同一时刻只能有一个线和至数据进行操作。
JDK中提供了很多atomic类,如AtomicInteger\AtomicBoolean\AtomicLong
,它们是通过CAS完成原子性。
JDK提供锁分为两种: synchronized依赖JVM实现锁,该关键字作用对象的作用范围内同一时刻只能有一个线程进行操作。另一种是LOCK,是JDK提供的
代码层面的锁,依赖CPU指令,代表性是ReentrantLock。
2)可见性 :一个线程对主内存的修改及时被其他线程看到。
JVM提供了synchronized和volatile,volatile的可见性是通过内存屏障和禁止重排序实现的,volatile会在写操作时,在写操作后加一条store屏障指令,将本地内存中的共享变量值刷新到主内存;会在读操作时,在读操作前加一条load指令,从内存中读取共享变量。
3)有序性:指令没有被编译器重排序。
可通过volatile、synchronized、Lock保证有序性。
10、两个进程同时要求写或者读,能不能实现?如何防止进程的同步?
我认为可以实现,比如两个进程都读取日历进程数据是没有问题,但同时写,应该会有冲突。
可以使用共享内存实现进程间数据共享。
11、线程间操作List
12、Java中对象的生命周期
1)创建阶段(Created): 为对象分配存储空间,开始构造对象,从超类到子类对static成员初始化;超类成员变量按顺序初始化,递归调用超类的构造方法,子类成员变量按顺序初始化,子类构造方法调用。
2)应用阶段(In Use): 对象至少被一个强引用持有着。
3)不可见阶段(Invisible): 程序运行已超出对象作用域
4)不可达阶段(Unreachable): 该对象不再被强引用所持有
5)收集阶段(Collected): 假设该对象重写了finalize()方法且未执行过,会去执行该方法。
6)终结阶段(Finalized): 对象运行完finalize()方法仍处于不可达状态,等待垃圾回收器对该对象空间进行回收。
7)对象空间重新分配阶段(De-allocated): 垃圾回收器对该对象所占用的内存空间进行回收或再分配,该对象彻底消失。
13、static synchronized 方法的多线程访问和作用
static synchronized
控制的是类的所有实例访问,不管new了多少对象,只有一份,所以对该类的所有对象都加了锁。限制多线程中该类的所有实例同时访问JVM中该类对应的代码。
14、同一个类里面两个synchronized方法,两个线程同时访问的问题
如果synchronized修饰的是静态方法,锁的是当前类的class对象,进入同步代码前要获得当前类对象的锁;
普通方法,锁的是当前实例对象,进入同步代码前要获得的是当前实例的锁;
同步代码块,锁的是括号里面的对象,对给定的对象加锁,进入同步代码块库前要获得给定对象锁;
如果两个线程访问同一个对象的synchronized方法,会出现竞争,如果是不同对象,则不会相互影响。
15、volatile的原理
有volatile变量修饰的共享变量进行写操作的时候会多一条汇编代码,lock addl $0x0,lock前缀的指令在多核处理器下会将当前处理器缓存行的数据会写回到系统内存,这个写回内存的操作会引起在其他CPU里缓存了该内存地址的数据无效。同时lock前缀也相当于一个内存屏障,对内存操作顺序进行了限制。
16、synchronized原理
synchronized通过对象的对象头(markword)来实现锁机制,java每个对象都有对象头,都可以为synchronized实现提供基础,都可以作为锁对象,在字节码层面synchronized块是通过插入monitorenter monitorexit
完成同步的。持有monitor对象,通过进入、退出这个Monitor对象来实现锁机制。
17、谈谈NIO的理解
NIO( New Input/ Output) 引入了一种基于通道和缓冲区的 I/O 方式,它可以使用 Native 函数库直接分配堆外内存,然后通过一个存储在 Java 堆的 DirectByteBuffer 对象作为这块内存的引用进行操作,避免了在 Java 堆和 Native 堆中来回复制数据。
NIO 是一种同步非阻塞的 IO 模型。同步是指线程不断轮询 IO 事件是否就绪,非阻塞是指线程在等待 IO 的时候,可以同时做其他任务。
同步的核心就是 Selector,Selector 代替了线程本身轮询 IO 事件,避免了阻塞同时减少了不必要的线程消耗;非阻塞的核心就是通道和缓冲区,当 IO 事件就绪时,可以通过写道缓冲区,保证 IO 的成功,而无需线程阻塞式地等待。
-
synchronized 和volatile 关键字的区别
-
synchronized与Lock的区别
-
ReentrantLock 、synchronized和volatile比较
1)volatile: 解决变量在多个线程间的可见性,但不能保证原子性,只能用于修饰变量,不会发生阻塞。volatile能屏蔽编译指令重排,不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面。多用于并行计算的单例模式。volatile规定CPU每次都必须从内存读取数据,不能从CPU缓存中读取,保证了多线程在多CPU计算中永远拿到的都是最新的值。
2)synchronized: 互斥锁,操作互斥,并发线程过来,串行获得锁,串行执行代码。解决的是多个线程间访问共享资源的同步性,可保证原子性,也可间接保证可见性,因为它会将私有内存和公有内存中的数据做同步。可用来修饰方法、代码块。会出现阻塞。synchronized发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生。非公平锁,每次都是相互争抢资源。
3) lock是一个接口,而synchronized是java中的关键字,synchronized是内置语言的实现。lock可以让等待锁的线程响应中断。在发生异常时,如果没有主动通过unLock()
去释放锁,则可能造成死锁现象,因此使用Lock时需要在finally块中释放锁。
4) ReentrantLock可重入锁,锁的分配机制是基于线程的分配,而不是基于方法调用的分配。ReentrantLock
有tryLock
方法,如果锁被其他线程持有,返回false,可避免形成死锁。对代码加锁的颗粒会更小,更节省资源,提高代码性能。ReentrantLock
可实现公平锁和非公平锁,公平锁就是先来的先获取资源。ReentrantReadWriteLock
用于读多写少的场合,且读不需要互斥场景。
-
ReentrantLock的内部实现
-
lock原理
-
死锁的四个必要条件?
-
怎么避免死锁?
-
对象锁和类锁是否会互相影响?
-
什么是线程池,如何使用?
-
Java的并发、多线程、线程模型
-
谈谈对多线程的理解
-
多线程有什么要注意的问题?
-
谈谈你对并发编程的理解并举例说明
-
谈谈你对多线程同步机制的理解?
-
如何保证多线程读写文件的安全?
-
多线程断点续传原理
-
断点续传的实现
5)并发编程有关知识点(这个是一般Android开发用的少的,所以建议多去看看):
平时Android开发中对并发编程可以做得比较少,Thread这个类经常会用到,但是我们想提升自己的话,一定不能停留在表面,,我们也应该去了解一下java的关于线程相关的源码级别的东西。
更多面试内容,面试专题,flutter视频 全套,音视频从0到高手开发。
关注GitHub:https://github.com/xiangjiana/Android-MS
题外话
不管怎么样,不论是什么样的大小面试,要想不被面试官虐的不要不要的,只有刷爆面试题题做好全面的准备,当然除了这个还需要在平时把自己的基础打扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊
这里我为大家准备了一些我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家~
欢迎评论区讨论。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
扎实,这样不论面试官怎么样一个知识点里往死里凿,你也能应付如流啊**
这里我为大家准备了一些我工作以来以及参与过的大大小小的面试收集总结出来的一套进阶学习的视频及面试专题资料包,主要还是希望大家在如今大环境不好的情况下面试能够顺利一点,希望可以帮助到大家~
[外链图片转存中…(img-Uui8No5y-1715354275085)]
欢迎评论区讨论。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!