Java常见面试题_2022最新版
- Java常见面试题_2022最新版持续更新中…
文章目录
一、线程基本概念的了解
什么是同步,什么是异步
- 同步:任务顺序执行,在上一个任务未执行完成之前下一个任务等待执行,顺序执行,一个执行完成才能继续执行下一个任务
- 异步:当上一个任务未完成之前,不需等待结果,继续执行后续的任务。
并发和并行的区别
- 并行:多个处理器或多核处理器同时处理多个任务。
- 并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。
并行:一群人分别在不同的售票窗口买票(排成多列)
并发:一群人在一个售票窗口排队买票(排成一列)
二、常见面试题
线程和进程的区别(什么是线程,什么是进程)
线程:进程中的一个执行任务(控制单元),负责当前进程中程序的执行。多个线程可共享同一个数据,共用所在进程的那一块内存空间。
进程:一个在内存中运行的应用程序。每个进程都有自己独立的一块内存空间。windows 中一个 运行的 .exe 就是一个进程
一个程序下至少有一个进程,一个进程下至少有一个线程,一个进程下也可以有多个线程来增加程序的执行速度。
线程有哪几种状态,分别是什么
- 新建(new)
- 就绪(可运行runnable)
- 运行(running)
- 阻塞(blocked)
- 死亡(结束dead)
启动线程需要调用什么方法
start()
线程调用 start 方法,处于什么状态
调用 start()
时处于就绪状态,当时间片分配到本线程时,才从就绪状态变为运行状态
线程中 run()和 start()有什么区别
start() 方法用于启动线程
run() 方法只是用于执行线程的运行时代码。
创建线程有哪几种方式?简述特点
- 继承 extends
Thread
- 实现 implements
Runnable
- 重写
run()
方法
- 重写
- 实现 implements
Callable
- 重写
call()
方法
- 重写
-
继承
Thread
public class MyThread extends Thread{ @Override public void run() { System.out.println("执行线程..."); } public static void main(String[] args) { Thread t = new MyThread(); t.start(); } }
-
实现
Runnable
public class MyRunnable implements Runnable{ @Override public void run() { System.out.println("执行线程任务..."); } public static void main(String[] args) { Runnable r = new MyRunnable(); Thread t = new Thread(r); t.start(); // new Thread(r).start(); // 还可以这样写 } }
-
实现
Callable
public class MyCallable implements Callable<Integer> { @Override public Integer call() throws Exception { System.out.println("执行线程..."); return 10; } public static void main(String[] args) { Callable c = new MyCallable(); FutureTask<Integer> f = new FutureTask(c); Thread t = new Thread(f,"有返回值的线程对象名字"); t.start(); try { System.out.println("线程的返回值 : " + f.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }
继承 Thread
比较有局限性,因为 Java 中是单一继承,多实现。我们一旦继承了 Thread
类就没办法继承其他父类了,这样不利于代码开发,而且数据就会变成线程所独享的了;
而如果实现了 Runnable
接口,不仅可以继续继承其他的类,而且可以把数据变成所有线程共享的,将线程任务放到线程中运行即可。
实现 Callable
可以通过 FutureTask
对象 get()
方法获取执行线程任务结束后的返回值,但是相对于 Thread
来讲,编程较为复杂。
sleep 和 wait 的区别
都是暂停的状态,都会让出CPU时间片,
- 类不同:
sleep()
是线程Thread
的静态方法wait()
是Object
类的方法
- 对于锁的释放:
sleep()
不释放锁,没有释放被占用的这个资源,其他线程不能使用这个资源wait()
释放锁,需要notify
或者notifyAll
才能唤醒当前线程
- 用途:
sleep()
暂停执行wait()
通常被用于线程间的通信
- 用法:
sleep()
任何地方都能使用wait()
只能用在同步方法或者同步块中
说说对锁的理解
锁是为了实现共享资源的同步,防止多线程并发情况(多线程可能对同一数据同时操作,导致数据出现异常),所以有了锁机制(synchronized,Lock);
什么是死锁(-)
当线程 A 持有独占锁 a,并尝试去获取独占锁 b 的同时,线程 B 持有独占锁 b,并尝试获取独占锁 a 的情况下,就会发生 AB 两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁。
如何避免死锁的发生(-)
(1)持有多个锁的话,锁的顺序要一致
(2)尽量避免锁的嵌套
(3)持有锁的方法尽量不要引用外部对象,可能外部对象也持有你的锁,会造成死锁
- 持久更新中…
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/107622.html