Java丨生产者与消费者模式 经典面试题

继续昨天遗留的问题:

1、生产者消费者模型的作用是什么
2、sleep方 法和wait方法有什么区别
3、如何在两个线程之间共享数据
4、为什么wait()方法和notify()/notifyAl()方法要在同步块中被调用
5、wait()方法和notify()/notifAIl()方法在放弃对象监视器时有什么区别.
6、Thread.sleep(0)的作用是什么

 

  • 生产者消费者模型的作用是什么?

这个问题很理论,但是很重要:

(1)通过平衡生产者的生产能力和消费者的消费能力来提升整个系统的运行效率,这是生产者消费者模型最重要的作用。

(2)解耦,这是生产者消费者附带的作用,解耦意味着生产者和消费者之间的联系少,联系越少越可以独自发展而不需要受到互相的制约。

 

 

  • sleep方 法和wait方法有什么区别

先了解他们的用处;

使用sleep方法实现,使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),释放CPU的时间片,具体取
决于系统定时器和调度程序的精度和准确性。线程不会丢失任何显示器的所有权。

使用wait方法实现,让线程暂时停止执行,释放CPU的时间片,并释放对象监视器的所有权,等待其它线程通过
notify方法来唤醒。

再了解它们的区别;

sleep()方法是Thread类的静态方法,不涉及到线程间同步概念,仅仅为了让一个线程自身获得一段沉睡时间。sleep可以在任何地方使用。
wait()方法是object类的方法,解决的问题是线程间的同步,该过程包含了同步锁的获取和释放,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify()方法才会重新激活调用者。
注意:线程调用notify()之后,只有该线程完全从 synchronized代码里面执行完毕后,monitor才会被释放,被唤醒线程才可以真正得到执行权。

 

  • 如何在两个线程之间共享数据

有两种方法来解决此类问题:

1、将共享数据封装成另外一个对象,然后将这个对象逐一传递给各个Runnable对象,每个线程对共享数据的操作方法也分配到那个对象身上完成,这样容易实现针对数据进行各个操作的互斥和通信

2、将Runnable对象作为一个类的内部类,共享数据作为这个类的成员变量,每个线程对共享数据的操作方法也封装在外部类,以便实现对数据的各个操作的同步和互斥,作为内部类的各个Runnable对象调用外部类的这些方法。

 

 

  • 为什么wait()方法和notify()/notifyAl()方法要在同步块中被调用

wait/notify是线程之间的通信,他们存在竞态,我们必须保证在满足条件的情况下才进行wait。换句话说,如果不加锁的话,那么wait被调用的时候可能wait的条件已经不满足了(如上述)。由于错误的条件下进行了wait,那么就有可能永远不会被notify到,所以我们需要强制wait/notify在synchronized中。

wait和notify是用于线程间通信。
以生产者消费者模式来说的话,就是生产者和消费者通过队列进行通信,既然他们通过同一个队列通信,那么对于队列的操作就一定要保证线程安全性。

 

  • wait()方法和notify()/notifAIl()方法在放弃对象监视器时有什么区别.

该wait()方法导致当前线程无限期地等待,直到另一个线程要么调用notify()此对象或notifyAll的() 。

该notify()方法用于唤醒正在等待到该对象的监视器接入线程。

该notifAIl()方法只是唤醒正在此对象的监视器上等待的所有线程。

唤醒的线程将以通常的方式完成 - 就像任何其他线程一样。

但是在我们允许它们继续执行之前,总是要定义快速检查继续执行线程所需的条件 - 因为可能存在某些情况下线程被唤醒而没有收到通知

  • Thread.sleep(0)的作用是什么

提醒操作系统立即再来异常CPU优先级计算,从而对线程进行调度

 

 

 

 

你可能感兴趣的:(Java【面试题】)