1.BIO、NIO、AIO是什么?
BIO :同步阻塞,服务器实现模式是一个连接一个线程,当客户端发来连接时服务器就需要启动一个线程进行处理,如果这个连接不做任何事情就会造成不必要的线程开销,当然线程池机制可以改善。
NIO:同步非阻塞,服务器实现模式为多个请求一个线程,即客户端发来的请求都会注册到多路复用器上,多路复用器轮训的连接有io请求时才开启一个线程进行处理。
AIO:异步非阻塞,服务器实现模式为多个有效请求一个线程。即客户端发来的请求由os处理完成才会通知服务器应用启动线程进行处理。
2.线程进程的区别
线程是进程划分成的更小的运行单位
线程和进程最大的不同在于基本上各进程是独立的,而各线程则不一定,因为同一进程中的线程极有可能会相互影响。线程执行开销小,但不利于资源的管理和保护;而进程正相反。3. 创建线程的⽅式?
继承Thread类或者实现runnable接口或者Callable接口
Callable接口有返回值,runnable没有
3.什么是死锁? 如何避免死锁?
线程死锁描述的是这样一种情况:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期地阻塞,因此程序不可能正常终止。
破坏请求和保持条件
破坏不可比剥夺条件
破坏环路请求等待
4.sleep与wait的区别?
共同点:两者都可以暂停线程的执行。
区别:
sleep()方法没有释放锁,而 wait() 方法释放了锁 。
wait()通常被用于线程间交互/通信,sleep()通常被用于暂停执行。
wait()方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象上的notify()或者notifyAll()方法sleep()方法执行完成后,线程会自动苏醒,或者也可以使用wait(long timeout)超时后线程会自动苏醒。
sleep()是Thread类的静态本地方法,wait()则是Object类的本地方法
5.为什么我们调⽤start⽅法时会执⾏run? 为什么我们不能直接调⽤run⽅法
这是另一个非常经典的 Java 多线程面试问题,而且在面试中会经常被问到。很简单,但是很多人都会答不上来!
new 一个Thread,线程进入了新建状态。调用start()方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。start()会执行线程的相应准备工作,然后自动执行run()方法的内容,这是真正的多线程工作。 但是,直接执行run()方法,会把run()方法当成一个 main 线程下的普通方法去执行,并不会在某个线程中执行它,所以这并不是多线程工作。
总结: 调用start()方法方可启动线程并使线程进入就绪状态,直接执行run()方法的话不会以多线程的方式执行。