多线程,高并发面试题 有用的地方不多 看1

27道多线程核心面试题(附答案),java线程join原理 流程: 1. 判断是否为可偏向状态–MarkWord中锁标志是否为‘01’,是否偏向锁是否为‘1’ 2. 如果是可偏向状态,则查看线程ID是否为当前线程,如果是,则进入步骤 ‘V’,否则进入步骤‘III’ 3. 通过CAS操作竞争锁,如果竞争成功,则将MarkWord中线程ID设置为当前线程ID,然后执行‘V’;竞争失败,则执行‘IV’ 4. CAS获取偏向锁失败表示有竞争。当达到safepoint时获得偏向锁的线程被挂起,偏向锁升级为轻量级锁,然后被阻塞在安全点的线程继续往下执行同步代码块 5. 执行同步 阅读详情
1. stop() 和 suspend() 方法为何不推荐使用?
反对使用 stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象
处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出
真正的问题所在。
suspend() 方法容易发生死锁。调用 suspend() 的时候,目标线程会停下来,但却仍
然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被 "挂
起" 的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任
何一个锁定的资源,就会造成死锁。所以不应该使用 suspend(),而应在自己的 Thread
类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用 wait()
命其进入等待状态。若标志指出线程应当恢复,则用一个 notify() 重新启动线程。
2. sleep() 和 wait() 有什么区别?
sleep 就是正在执行的线程主动让出 cpu,cpu 去执行其他线程,在 sleep 指定的时
间过后,cpu 才会回到这个线程上继续往下执行,如果当前线程进入了同步锁,sleep
方法并不会释放锁,即使当前线程使用 sleep 方法让出了 cpu,但其他被同步锁挡住
了的线程也无法得到执行。wait 是指在一个已经进入了同步锁的线程内,让自己暂时
让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用
了 notify 方法(notify 并不释放锁,只是告诉调用过 wait 方法的线程可以去参与获
得锁的竞争了,但不是马上得到锁,因为锁还在别人手里,别人还没释放。如果 notify
多线程 / 高并发方法后面的代码还有很多,需要这些代码执行完后才会释放锁,可以在 notfiy 方法后
增加一个等待和一些代码,看看效果),调用 wait 方法的线程就会解除 wait 状态和
程序可以再次得到锁后继续向下运行。
3. 同步和异步有何异同,在什么情况下分别使用他们?
如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读
的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等
待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
4. 当一个线程进入一个对象的一个 synchronized 方法后,其它线程是否可进入此对象的其
它方法?
• 其他方法前是否加了 synchronized 关键字,如果没加,则能。
• 如果这个方法内部调用了 wait,则可以进入其他 synchronized 方法。
• 如果其他个方法都加了 synchronized 关键字,并且内部没有调用 wait,则不
能。
• 如果其他方法是 static,它用的同步锁是当前类的字节码,与非静态的方法不
能同步,因为非静态的方法用的是 this。
5. 简述 synchronized 和 java.util.concurrent.locks.Lock 的异同?
主要相同点:Lock 能完成 synchronized 所实现的所有功能。
主要不同点:Lock 有比 synchronized 更精确的线程语义和更好的性能。
synchronized 会自动释放锁,而 Lock 一定要求程序员手工释放,并且必须在 finally 从句中释放。Lock 还有更强大的功能,例如,它的 tryLock 方法可以非阻塞方式去拿
锁。
举例说明(对下面的题用 lock 进行了改写)
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest {
/**
* @param args
*/
private int j;
private Lock lock = new ReentrantLock();
public static void main(String[] args) {
// TODO Auto-generated method stub
ThreadTest tt = new ThreadTest();
for(int i=0;i<2;i++)
{
new Thread(tt.new Adder()).start();
new Thread(tt.new Subtractor()).start();
}
} private class Subtractor implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
/*synchronized (ThreadTest.this) {
System.out.println("j--=" + j--);
//这里抛异常了,锁能释放吗?
}*/
lock.lock();
try
{
System.out.println("j--=" + j--);
}finally
{
lock.unlock();
}
}
} }
private class Adder implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
/*synchronized (ThreadTest.this) {
System.out.println("j++=" + j++);
}*/
lock.lock();
try
{
System.out.println("j++=" + j++);
}finally
{
lock.unlock();
}
}
} }
}
6. 概括的解释下线程的几种可用状态。
• 新建 new。
• 就绪 放在可运行线程池中,等待被线程调度选中,获取 cpu。
• 运行 获得了 cpu。
• 阻塞
o 等待阻塞 执行 wait() 。
o 同步阻塞 获取对象的同步琐时,同步锁被别的线程占用。
o 其他阻塞 执行了 sleep() 或 join() 方法)。
• 死亡。
7. 什么是 ThreadLocal?
ThreadLocal 用于创建线程的本地变量,我们知道一个对象的所有线程会共享它的全
局变量,所以这些变量不是线程安全的,我们可以使用同步技术。但是当我们不想使用
同步的时候,我们可以选择 ThreadLocal 变量。
每个线程都会拥有他们自己的 Thread 变量,它们可以使用 get()\set() 方法去获取他
们的默认值或者在线程内部改变他们的值。ThreadLocal 实例通常是希望它们同线程
状态关联起来是 private static 属性。
8. run() 和 start() 区别。
run( ):只是调用普通 run 方法start( ):启动了线程, 由 Jvm 调用 run 方法
启动一个线程是调用 start() 方法,使线程所代表的虚拟处理机处于可运行状态,这意
味着它可以由 JVM 调度并执行。这并不意味着线程就会立即运行。run() 方法可以产
生必须退出的标志来停止一个线程。
9. 请说出你所知道的线程同步的方法。
wait():使一个线程处于等待状态,并且释放所持有的对象的 lock。 sleep():使一个
正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉
InterruptedException 异常。 notify():唤醒一个处于等待状态的线程,注意的是在
调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由 JVM 确定唤醒
哪个线程,而且不是按优先级。 notityAll():唤醒所有处入等待状态的线程,注意并
不是给所有唤醒线程一个对象的锁,而是让它们竞争。
10. 线程调度和线程控制。
线程调度(优先级)
:
与线程休眠类似,线程的优先级仍然无法保障线程的执行次序。只不过,优先级高的线
程获取 CPU 资源的概率较大,优先级低的并非没机会执行。
线程的优先级用 1-10 之
间的整数表示,数值越大优先级越高,默认的优先级为 5。 在一个线程中开启另外一
个新线程,则新开线程称为该线程的子线程,子线程初始优先级与父线程相同。
线程控制
• sleep( ) // 线程休眠 join( ) // 线程加入 yield( ) // 线程礼让
setDaemon( ) // 线程守护中断线程
• stop( ) interrupt( ) ==(首先选用)==
11. 什么是线程饿死,什么是活锁?
当所有线程阻塞,或者由于需要的资源无效而不能处理,不存在非阻塞线程使资源可用。
JavaAPI 中线程活锁可能发生在以下情形:
• 当所有线程在序中执行 Object.wait(0),参数为 0 的 wait 方法。程序将发生
活锁直到在相应的对象上有线程调用 Object.notify() 或者 Object.notifyAll()。
• 当所有线程卡在无限循环中。
12. 多线程中的忙循环是什么?
忙循环就是程序员用循环让一个线程等待,不像传统方法 wait(), sleep() 或 yield() 它
们都放弃了 CPU 控制,而忙循环不会放弃 CPU,它就是在运行一个空循环。这么做
的目的是为了保留 CPU 缓存。
在多核系统中,一个等待线程醒来的时候可能会在另一个内核运行,这样会重建缓存。
为了避免重建缓存和减少等待重建的时间就可以使用它了。
13. volatile 变量是什么?volatile 变量和 atomic 变量有什么不同?
volatile 则是保证了所修饰的变量的可见。因为 volatile 只是在保证了同一个变量在
多线程中的可见性,所以它更多是用于修饰作为开关状态的变量,即 Boolean 类型的
变量。volatile 多用于修饰类似开关类型的变量、Atomic 多用于类似计数器相关的变量、其
它多线程并发操作用 synchronized 关键字修饰。
volatile 有两个功用:
• 这个变量不会在多个线程中存在复本,直接从内存读取。
• 这个关键字会禁止指令重排序优化。也就是说,在 volatile 变量的赋值操作后
面会有一个内存屏障(生成的汇编代码上),读操作不会被重排序到内存屏障
之前。
14. volatile 类型变量提供什么保证?能使得一个非原子操作变成原子操作吗?
volatile 提供 happens-before 的保证,确保一个线程的修改能对其他线程是可见的。
在 Java 中除了 long 和 double 之外的所有基本类型的读和赋值,都是原子性操作。
而 64 位的 long 和 double 变量由于会被 JVM 当作两个分离的 32 位来进行操
作,所以不具有原子性,会产生字撕裂问题。但是当你定义 long 或 double 变量时,
如果使用 volatile 关键字,就会获到(简单的赋值与返回操作的)原子性。
java高分面试指南:java高并发秒杀面试题 一,session共享 首先第一个要解决的就是sesison共享的问题,如下图。 通常有两种解决方案,第1种是配置nginx的负载集群策略为ip_hash,第2种是将session存储到其它地方,一般推荐放到redis中。 第1种方案适合于临时解决或者是为了兼容历史项目,但是从应用服务器无状态的角度考虑,推荐把用户会话session放到redis,如下图。 二,本地缓存 如果使用本地缓存,当从单体迁移到集群后,就会面临缓存同步的问题,如下图。 最佳实践是上分布式缓存,既解决了缓存同步的问题,也释放了应 阅读详情

相关推荐

高并发常见面试题(深入底层).docx

花费数天时间整理的常见大厂问的高并发常见面试题,里面有代码(深入底层+代码解读)

面试必看,多线程并发面试题合集

什么是java中的线程? 线程可以理解为一个轻量化进程。是进程的最小部分,可以与进程的其他部分(线程)并发执行。 什么是多线程? 多线程是多个线程并发执行。Java支持多线程,因此它允许应用程序并发执行两个或多个任务。 在java中创建线程的方法是什么? 有两种方式创建线程: ​ 继承Thread类 ​ 实现Runnable接口 但是本质上最终都是创建Thread类。 Thread和Runnable哪个更好? 实现Runnable接口被认为是比继承Thread类更好的方法,原因如下: Java不支持多重继

小黑说Java 2440

多线程高并发面试题.pdf

在学习Java过程中,自己收集了很多的Java的学习资料,分享给大家,有需要的欢迎下载,希望对大家有用,一起学习,一起进步。

多线程高并发(全网最新:面试题 + 导图 + 笔记)面试手稳心不慌

移动时代、5G 时代、物联网时代的大幕已经开启,新时代提升了对 Java 应用的高性能、高并发的要求,也抬升了 Java 工程师的技术台阶和面试门槛。当你开始开始去跳槽面试的时候,明明只是一份 15K 的工作,却问你会不会多线程,懂不懂高并发,火箭造得让你猝及不防,结果就是凉凉;很多公司的面试题从某个侧面反映了生产场景的技术要求。之前只有 BAT 等大公司才有高并发技术相关的面试题,现在与 Java 项目相关的整个行业基本都涉及此类面试题。现如今市场,多线程高并发编程、分布式、负载均衡、集群等可以说是现在

weixin_70730532的博客 819

80后秃头程序员失眠整理的:Java多线程高并发面试题,真的太难了

ThreadLocal为每个线程的中并发访问的数据提供一个副本,通过访问副本来运行业务,这样的结果是耗费了内存,单大大减少了线程同步所带来性能消耗,也减少了线程并发控制的复杂度。} }}, "线程 2").start();如果每次运行结果和单线程运行的结果是一样的,而且其他的变量 的值也和预期的是一样的,就是线程安全的。对象都在堆里创建,为了提升效率线程会从堆中弄一个缓存到自己 的栈,如果多个线程使用该变量就可能引发问题,这时volatile 变量就可以发挥作用了,它要求线程从主存中读取变量的值。

KRYST4L123的博客 368

绝了,66道并发多线程面试题汇总

线程是操作系统能够进⾏运算调度的最⼩单位,它被包含在进程之中,是进程中的实际运作单位,可以使⽤多线程对进⾏运算提速。线程安全:就是多线程访问时,采⽤了加锁机制,当⼀个线程访问该类的某个数据时,进⾏保护,其他线程不能进⾏访问,直到该线程读取完,其他线程才可使⽤。不会出现数据不⼀致或者数据污染。Vector 是⽤同步⽅法来实现线程安全的, ⽽和它相似的ArrayList不是线程安全的。

程序员高级码农的博客 1925

多线程常见的面试题

多线程常见的面试题1. 什么是线程和进程? 线程与进程的关系,区别及优缺点? 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。 在 Java 中,当我们启动 main 函数时其实就是启动了一个 JVM 的进程,而 main 函数所在的线程就是这个进程中的一个线程,也称主线程。 如下图所示,在 windows 中通过查看任务管理器的方式,我们就可以清楚看到 window 当前运行的进程(.exe 文件的运行)。 线程与进程相似,

上山打卤面的博客 1万+

一文看懂【多线程高并发

本文系统梳理了Java多线程高并发的核心知识点,包括线程基础(状态、创建方式、JMM模型)、线程池参数与执行流程、各类锁机制(可重入锁、乐观/悲观锁等)、AQS同步器原理,以及线程协调工具(CountDownLatch、Semaphore)的使用场景。重点对比了协程与线程的特性差异,指出协程在用户态调度、轻量级和低切换开销方面的优势。同时总结了ReentrantLock、synchronized等锁的实现原理,并强调虚拟线程在JDK21+中对IO密集型应用的性能提升。全文以技术要点罗列为主,涵盖多线程编程

G_G_S的博客 875

多线程高并发java中高级工程师面试题及答案

什么是ActiveMQ?ActiveMQ服务器宕机怎么办?丢消息怎么办?持久化消息非常慢怎么办?消息的不均匀消费怎么办?死信队列怎么办?ActiveMQ中的消息重发时间间隔和重发次数吗?

m0_54816834的博客 922

JAVA面试题知识总结——JVM多线程、线程池、高并发、事务、微服务、springcloud

本文通过面试题的知识点方向,总结整合了有关JVM多线程、线程池、高并发、事务相关的知识点,望对读友有用,本文很长,可以关注后每天看一个方向的知识点即可。

qq_41930763的博客 1059

高并发问题面试

高并发场景下,如何解决数据库与缓存双写的时候数据不一致的情况?如何解决大value缓存的全量更新效率低下问题?

.net 面试题(高级开发人员篇)

.net 面试题(高级开发人员篇) 内有答案哦^_^

跳槽入职字节跳动,给到20K16薪,只因比别人更懂多线程高并发(1)

在找工作的时候,除了做些相关面试和准备熟悉以前做的项目之外,还应该学习新的知识。毕竟,每多学一点,成功找到工作的机会就大一点。而且,IT这行,技术发展过于快速,如果没有学习新知识的动力,终究会被淘汰。

2301_82244343的博客 698

java sql锁住一行_高并发Java多线程编程基础

目前我接触的多线程编程基本上都是基于java.util.concurrent 这个包下的开发的,下面就以这个包来分析Java多线程高并发一、分析面试题1.在java中wait和sleep方法的不同?最大的不同是在等待时wait会释放锁,而sleep一直持有锁。Wait通常被用于线程间交互,sleep通常被用于暂停执行。2.创建多线程的三种方法(1)继承Thread()(2)实现Runnable...

weixin_33615688的博客 260

多线程高并发的常见面试题整理

1.线程实现方式 1继承Thread类 定义Thread类的子类,并重写Thread类的run()方法,创建子类对象(即线程对象),调用线程对象的start()方法来启动该线程 2.实现Runnable接口 并重写该接口的run()方法,该run()方法同样是该线程的执行体。创建该Runnable实现类的实例,并将此实例作为Thread的target(即构造函数中的参数)来创建Thread对象(该Thread对象才是真正的线程对象,只是该Thread对象负责执行其target的run()方法)。最后调用线程

zhangqiang180的博客 8236

面试题:Nginx 是如何实现高并发?常见的优化手段有哪些?

面试题:Nginx 是如何实现并发的?为什么 Nginx 不使用多线程?Nginx常见的优化手段有哪些?502错误可能原因有哪些?面试官心理分析主要是看应聘人员的对NGINX的基本原理是否熟悉,因为大多数运维人员多多少少都懂点NGINX,但是真正其明白原理的可能少之又少。明白其原理,才能做优化,否则只能照样搬样,出了问题也无从下手。懂皮毛的人,一般会做个 Web Server,搭建一个 Web 站...

weixin_33826268的博客 1706

【成神之路】多线程并发相关面试题

基本概念: 说说线程安全问题,什么是线程安全,如何保证线程安全 函数、函数库在并发环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成。 代码在多线程下执行和在单线程下执行永远都能获得一样的结果,那么你的代码就是线程安全的。 这个问题有值得一提的地方,就是线程安全也是有几个级别的: (1)不可变 像String、Integer、Long这些,都是final类型的类,...

Franco的博客 3726

java 多线程并发 面试_JAVA多线程高并发面试题总结

ReadMe:括号里的内容为补充或解释说明。多线程高并发是毕业后求职大厂面试中必问的知识点,自己之前总是面试前才去找相关的知识点面试题来背背,隔段时间又忘了,没有沉淀下来,于是自己总结了下相关的知识点。多线程1. 什么是进程?线程?区别?1)进程是一个独立的运行环境,它可以被看作是一个程序或者一个应用。而线程是在进程中执行的一个任务。eg:打开360安全卫士,它本身是一个程序,也是一个进程,...

weixin_36280338的博客 221
上一篇: JVM最新面试题 有用地方不多 看1
下一篇: 11
okbin1991
博客等级 码龄9年 374粉丝 · 747原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值