面试之线程

Posted Talk is cheap. Show me the cod

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试之线程相关的知识,希望对你有一定的参考价值。

一、JDK、JRE和JVM三者之间关系:  

1、所有的JAVA程序都会被编译成class文件,由虚拟机JVM和操作系统交互
2、JVM需要调用解释所需要的类库lib才可以执行class文件,JVM+lib=JRE即JAVA运行环境
3、JDK主要用于程序开发,最主要是编译器,包含了JRE,JAVA工具类和JAVA基础类库

 

二、怎么实现线程

实现Runnable接口或者继承Thread类来实现,当你打算多重继承时,优先选择实现Runnable

三、Thread.start()与Thread.run()有什么区别

调用start()后,线程会被放到等待队列,等待CPU调度。然后通过JVM,线程Thread会调用run()方法,执行本线程的线程体

四、为什么需要run()和start()方法,我们可以只用run()方法来完成任务吗

start()用来启动一个线程,当调用start()方法时,系统才会开启一个线程。run()只是一个线程里的一个函数,和多线程无关

 1 public synchronized void start() {
 2         if (threadStatus != 0)
 3             throw new IllegalThreadStateException();
 4         group.add(this);
 5 
 6         boolean started = false;
 7         try {
 8             start0();
 9             //private native void start0(),使用native修饰,Thread类要调用本地方法,要向JVM注册,这个方法调用了run方法
10             started = true;
11         } finally {
12             try {
13                 if (!started) {
14                     group.threadStartFailed(this);
15                 }
16             } catch (Throwable ignore) {
17             }
18         }
19     }

五、什么是ThreadLocal类,怎么使用它

通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改

六、什么时候抛出InvalidMonitorStateException异常,为什么

调用wait()/notify()/notifyAll()中的任何一个方法时,如果当前线程没有获得该对象 的锁,那么就会抛出IllegalMonitorStateException的异常

七、多线程中sleep、supend和wait区别

共同点:都会阻塞当前线程

不同点:

  1、sleep不会交出任何已获得的对象锁,是Thread类的方法,是线程用来控制自身流程的,调用此方法要捕捉InterruptedException异常

  2、wait会交出调用wait对象的对象锁。是Object类中定义的方法,用来线程间的通信,而且wait存在notify方法来唤醒调用wait的线程。

  3、suspend,使线程进入停滞状态,除非收到resume消息,否则该线程不会变回可执行状态

八、多线程中wait/notify区别

1、wait() 与 notify/notifyAll 方法必须在同步代码块中使用

  wait() 与 notify/notifyAll() 是Object类的方法,在执行两个方法时,要先通过synchronized[‘s??kr?na?zd]获得锁

2、notify/notifyAll()执行后,并不立即释放锁,而是要等到执行完临界区中代码后,再释放

3、多线程中测试某个条件的变化用 if 还是用 while?

List中没有数据了,再还是有线程去执行删除数据的操作。因此,需要用while循环来判断条件的变化,而不是用if

九、在静态方法上使用同步时会发生什么事

Synchronized修饰静态方法,实际上是对该类对象加锁,俗称“类锁”

答案:http://blog.csdn.net/u010842515/article/details/65443084

十、Thread的join方法

1、Thread类中的join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行

2、join方法必须在线程start方法调用之后调用才有意义

3、join方法的原理就是调用相应线程的wait方法进行等待操作的,例如A线程中调用了B线程的join方法,则相当于在A线程中调用了B线程的wait方法,当B线程执行完(或者到达等待时间),B线程会自动调用自身的notifyAll方法唤醒A线程,从而达到同步的目的

十一、死锁

形成原因:循环等待,多线程申请多资源,形成了循环等待

1、互斥:进程在某一时间内独占资源;
2、持有:一个进程因请求资源而阻塞时,对已获得的资源保持不放;
3、不可剥夺:进程已获得资源,在末使用完之前,不能强行剥夺;
4、环形等待:若干进程之间形成一种头尾相接的循环等待资源关系;

解决方法:

1、针对2和3,引入事务机制,将所有上锁操作均作为事务对待,一旦开始上锁,即确保全部操作均可回退,同时通过锁管理器检测死锁,并剥夺资源

2、针对4,约定上锁的顺序必须一致

3、在尝试获取锁的时候加一个超时时间

4、死锁检测机制

每当一个线程获得了锁,会在线程和锁相关的数据结构中(map、graph等等)将其记下。除此之外,每当有线程请求锁,也需要记录在这个数据结构中。
当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生。

 

以上是关于面试之线程的主要内容,如果未能解决你的问题,请参考以下文章

Java进阶之光!2021必看-Java高级面试题总结

Java工程师面试题,二级java刷题软件

经验总结:Java高级工程师面试题-字节跳动,成功跳槽阿里!

JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段

Java面试准备之多线程

并发编程之多线程基础篇及面试