AcWing
  • 首页
  • 活动
  • 题库
  • 竞赛
  • 校园
  • 应用
  • 文章
    • 题解
    • 分享
    • 问答
  • 吐槽
  • 登录/注册

面试深入之java多线程

作者: 作者的头像   大菜狗 ,  2022-06-22 17:45:30 ,  所有人可见 ,  阅读 21


1


面试深入之java多线程

使用多线程的方式

1.继承Thread类

缺点:java语言不支持多继承

Thread类底层也是实现的Rannable,执行run方法的调用顺序与其执行顺序无关

2.实现Runnable接口

在run方法前添加 synchronized关键字,可以使多个线程在执行 run 方法时,以排队的方式进行处理。

多线程共享变量可能引发的问题

实例与变量的线程安全问题

1.在使用synchronized关键字修饰方法时,在多线程情况下会出现指令重排问题

在某些 JVM 中, i– 的操作要分成如下 3 步:
1)取得原有ⅰ值。
2)计算 i-1。
3)对i进行赋值。
在这3个步骤中,如果有多个线程同时访问,那么一定会出现非线程安全问题。

2.一个书中的案例:

用println打印全局变量的$i–$,在多线程环境下会引发线程安全问题,因为:

虽然$println()$方法在内部是同步的,但$i–$的操作却是在进入$println()$之前发生的,所以有发生非线程安全问题的概率,

常用方法

1.currentTread0方法

可以返回该方法在被哪个线程调用,书中案例为:构造方法被main线程调用,run方法被Thread线程调用

isAlive()方法

可以判断线程当前是否在活动状态

停止线程

1.interrupet()停止线程

书中案例:在for循环中停止的线程,for循环下面的语句还可以正常输出;要解决这一问题,可以将代码块放入try中,并在for循环内抛出异常

2.在sleep状态下停止线程

如果在sleep状态下停止线程,则会进入catch语句,并清除停止的状态值

如果先停止再sleep,则会进入catch

3.用stop()方法停止线程

会造成数据不一致的后果,所以已经作废

暂停线程

suspend与resume方法

缺点:

1.独占:在使用suspend与resume方法时,如果使用不当,极易造成公共的同步对象的独占,使得其他线程无法访问公共同步对象。

2.不同步:会造成因线程暂停导致数据不同步的情况

线程的优先级

可以使用setPriority()方法设置线程的优先级,优先级为$1-10$

优先级具有继承的特性:A线程调用的B线程,B线程会继承A线程的优先级

线程先执行不代表先执行完,线程的优先级具有随机性

守护线程

线程分为2种,一种为用户线程,一种为守护线程

main线程和GC线程是经典的两个守护线程

对象和变量的并发访问

“非线程安全”其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,

产生的后果就是“脏读”,也就是取到的数据其实是被更改过的。而“线程安全”就是以获得的实例变量的值是经过同步处理的,不会出现脏读的现象。

方法内的变量是线程安全的

synchronized

1.锁的是谁?

关键字synchronized 取得的锁都是对象锁,而不是把一段代码或方法(函数)当作锁,哪个线程先执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁 Lock;

也就是说,一个线程调用某个对象的方法时,这个对象就被锁住了,如果有另一个线程调用该对象的其他方法,就只能等待持有锁的线程把锁释放

但如果多个线程访问多个对象,则 JVM 会创建多个锁。

2.synchronized的性质

1.是可重入锁

可重人锁的概念是:自己可以再次获取自己的内部锁。
比如有1条线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果不可重人的话,就会造成死锁。

2.是悲观锁

3.出现异常自动释放

4.同步不可继承

父类中的方法用synchronized修饰,子类在继承这个方法时,不会同时继承锁

3.弊端及其解决方案(同步代码块)

如果一个对象长时间的持有锁,其他对象只能等待,就会等待很久

解决方案:使用同步代码块

方法内部的同步代码块,形如:

synchronized (this) {
//you code
}

而不是在方法上加synchronized,这样就做到了:在方法中:不在代码块中的语句异步执行,代码块中的语句同步执行

当有多个同步代码块时,当线程访问一个同步代码块,其他代码块将被阻塞;即多个同步代码块之间也是同步(按顺序执行的)

synchronized与synchronized (this)都是锁的对象

4.synchronized与synchronized (this)异同

书上的大段原话

多个线程调用同一个对象中的不同名称的 synchronized 同步方法或 synchronized(this)同步代码块时,调用的效果就是按顺序执行,也就是同步的,阻塞的。这说明synchronized 同步方法或 synchronized(this)同步代码块分别有两种作用。

1.synchronized同步方法:

  1. 对其他synchronized 同步方法或 synchronized(this) 同步代码块调用呈阻塞状态。
  2. 同一时间只有一个线程可以执行 synchronized 同步方法中的代码。

2.synchronized(this)同步代码块

  1. 对其他synchronized 同步方法或 synchronized(this) 同步代码块调用呈阻塞状态。
  2. 同一时间只有一个线程可以执行 synchronized(this)同步代码块中的代码。

其实Java还支持对“任意对象”作为“对象监视器”来实现同步的功能。这个“任意对象”大多数是实例变量及方法的参数,使用格式为synchronized(非this对象).

5.同步代码块synchronized(任意对象)做对象监视器

1)当多个线程同时执行 synchronized(x)(} 同步代码块时呈同步效果。
2)当其他线程执行ⅹ对象中synchronized 同步方法时呈同步效果。
3)当其他线程执行ⅹ对象方法里面的synchronized(this)代码块时也呈现同步效果。
但需要注意:如果其他线程调用不加 synchronized 关键字的方法时,还是异步调用。

6.synchronized应用在静态方法前锁Class

和将 synchronized 关键字加到非static 方法上使用的效果是一样的。其实还是有本质上的不同的,synchronized 关键字加到static静态方法上是给 Class 类上锁,而synchronized 关键字加到非static 静态方法上是给对象上锁。

7.synchronized与String连用时的问题

synchronized(String)使用时会由于jvm中有string常量池缓存功能,导致多个线程持有相同的锁,所以同步代码块不与String连用

如果非要实现字符串的操作可以用new String()解决,原因如下:

Object a = new String("A");
Object b = new String("B");
System.out.println(a.hashCode()==b.hashCode());
String c = "B";
String d = "B";
System.out.println(c.hashCode()==d.hashCode());
//输出结果为:
//false
//true

原因猜想:用new关键字,定义出两个不同的字符串对象,直接写两个相同的字符串,在常量池中是同一个对象

volatile

Java编程语言允许线程访问共享变量,为了确保共享变量能被准确和一致地更新,线程应该确保通过排他锁单独获得这个变量。Java语言提供了volatile,在某些情况下比锁要更加方便。

与vlolatile实现相关一些名词解释

JMM名词解释.png

1)将当前处理器缓存行的数据写回到系统内存。
2)这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效。

Java内存模型的基础

在并发编程中,需要处理两个关键问题:线程之间如何通信及线程之间如何同步

线程之间的通信机制有两种:共享内存和消息传递。

在执行程序时,为了提高性能,编译器和处理器常常会对指令做重排序。重排序分3种类型。

1)编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句
的执行顺序。
2)指令级并行的重排序。现代处理器采用了指令级并行技术(Instruction-Level
Parallelism,ILP)来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应
机器指令的执行顺序。
3)内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上
去可能是在乱序执行。

2和3属于处理器重排序

JMM的编译器重排序规则会禁止特定类型的编译器重排
序(不是所有的编译器重排序都要禁止)。对于处理器重排序,JMM的处理器重排序规则会要
求Java编译器在生成指令序列时,插入特定类型的内存屏障(Memory Barriers,Intel称之为
Memory Fence)指令,通过内存屏障指令来禁止特定类型的处理器重排序。

0 评论

你确定删除吗?

© 2018-2022 AcWing 版权所有  |  京ICP备17053197号-1
用户协议  |  常见问题  |  联系我们
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息