Java面试大全(2020年版)161-170

161.同步和异步有何不同,在什么情况下分别使用它们?举例说明

如果数据将在线程间共享。例如:正在写的数据以后可能会被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效。
同步交互:指发送一个请求,需要等待返回,然后才能发送下一个请求,有个等待的过程
异步交互:指发送一个请求,不需要等待返回,随时可以再发送下一个请求,即不需要等待。
区别:一个需要等待,一个不需要等待

162.Thread类中的strat()和run()方法有什么区别?

start()方法被用来启动新创建的线程,而且start()内部调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会在原来的线程中调用,没有新的线程启动,而调用start()方法会启动一个新的线程。

163.java中Runnable和Callable的区别

Runnable和Callable都代表那些要在不同的线程中执行的任务。Runnable从JDK1.0开始就有了,Callable是在JDK1.5增加的。
他们的主要区别是Callable的call()方法可以返回值和抛出异常,而Runnable的run()方法没有这些功能。Callable可以返回装载有计算结果的Future对象。

164.什么是线程安全?

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果都是一样的,而且其他变量的值也和预期的是一样的,就是线程安全的。一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。

165.如何在两个线程间共享数据?

可以通过共享对象来实现这个目的,或者是使用阻塞队列,或者使用wait()和notify()方法

167.锁池和等待池

锁池:假设线程A已经拥有了某个对象的锁,而其它的线程想要调用这个对象的某个Synchronized方法(或者Synchronized代码块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这个线程就进入了该对象的锁池中
等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到该对象的等待池中。

168.什么是FutureTask?

在java并发程序中FutureTask表示一个可以取消的异步运算。它有启动和取消运算、查询运算是否完成和取回运算结果等方法。只有当运算完成的时候结果才能返回,如果运算尚未完成,get()方法将会阻塞。一个FutureTask对象可以对调用了Callable和Runnable的对象进行包装,由于FutureTask也是调用了Runnbale接口所以它可以提交给Executor来执行

169.为什么你应该在循环中检查等待条件

处于等待状态的线程可能会受到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就会在没有满足结束条件的情况下推出。因此,当一个等待线程醒来时,不能认为它原来的等待状态仍然是有效的,在notify()方法调用之后和等待线程醒来之前这段时间它可能会改变。这就是在循环中使用wait()方法效果更好的原因。

170.java中堆和栈有什么不同?

为什么把这个问题归类在多线程和并发面试题里?因为栈是一块和线程紧密相关的内存区域。每个线程都有自己的栈内存,用于存储本地变量、方法参数和栈调用,一个线程中存储的变量对其他线程是不可见的。而堆是所有线程共享的一片公共内存区域。对象都在堆里创建,为了提升效率,线程会从堆中弄一个缓存到自己的栈,如果多个线程使用该变量就可能引发问题,这时volatile变量就可以发挥作用了,它要求线程从主存中读取变量的值

原创文章 57 获赞 4 访问量 2682

猜你喜欢

转载自blog.csdn.net/m0_47572402/article/details/106139355