一个监视器和一个信号量的主要区别是什么?
一个监视器和一个信号量的主要区别是什么?
监视器是一种旨在被多个线程访问的对象。监视器对象的成员函数或方法将实施互斥,因此在任何给定时间只有一个线程可以对对象执行任何操作。如果一个线程正在执行对象的成员函数,则任何试图调用该对象的成员函数的其他线程都必须等待直到第一个线程完成。
信号量是一种较低级别的对象。您可以使用信号量来实现监视器。信号量本质上只是一个计数器。当计数器为正时,如果线程尝试获取信号量,则允许它,并且计数器减1。当线程完成后,它释放信号量并增加计数器。
如果当一个线程尝试获取信号量时,计数器已经为零,则它必须等待直到另一个线程释放信号量。如果有多个线程正在等待时,当一个线程释放信号量时,其中一个线程将获得它。释放信号量的线程不必是获取信号量的线程。
监视器就像公共厕所。只能一个人进入。他们锁定门以防止其他人进入,完成后再解锁。
信号量就像自行车租赁场所。他们有一定数量的自行车。如果您尝试租用一辆自行车,他们有一辆空闲的,那么您可以拿走它,否则您必须等待。当有人归还自行车时,其他人可以拿走它。如果您有自行车,则可以将其交给其他人归还---自行车租赁场所不在乎谁归还它,只要他们拿回自行车即可。
链接: here 了解更多信息。希望能对您有所帮助。
java.util.ArrayList
:它是一个对象还是多个对象的容器?嗯,它同时具备两者特性。那么,使用信号量来控制对它的访问是否合适?我会说:不合适。 - dma_k简短回答:
监视器:在监视器中一次只能控制一个线程执行(需要获取锁才能执行单个线程)。
信号量:用于保护共享资源的锁(需要获取锁才能访问资源)。
信号量(semaphore)是一种用于协调线程之间的信号传递机制。例如:一个线程正在从互联网下载文件,另一个线程正在分析这些文件。这是经典的生产者/消费者场景。当一个文件下载完成时,生产者会在信号量上调用 signal()
方法。消费者会在同一信号量上调用 wait()
方法以阻塞自身,直到接收到信号后才继续运行。如果在消费者调用 wait 时,信号量已经被唤醒了,则此次调用不会阻塞。多个线程可以等待同一个信号量,但每个信号只会解锁一个线程。
计数信号量(counting semaphore)会记录信号的数量。例如,如果生产者连续发出三个信号,wait()
可以被调用三次而不会阻塞。二元信号量(binary semaphore)不计数,只有“等待”和“唤醒”两个状态。
互斥锁(mutex,mutual exclusion lock)是由单个线程拥有的锁,只有获得锁的线程才能释放它。其他试图获取该锁的线程将被阻塞,直到当前所有者线程释放该锁。互斥锁本身并不锁定任何内容,它只是一个标志。但代码可以检查互斥锁的所有权,以确保一次只能有一个线程访问某个对象或资源。
监视器(monitor)是更高级别的构造,它使用底层互斥锁来确保对某个对象的线程安全访问。不幸的是,“监视器”这个词在不同的上下文和平台中有着不同的含义,但例如在Java中,“监视器”是与对象隐式关联的互斥锁,并且可以使用 synchronized
关键字调用。 synchronized
关键字可应用于类、方法或块,并确保一次只有一个线程可以执行该代码。
信号量:
在并发系统中使用计数器或标志来控制访问共享资源,这就需要使用信号量。
例如:
标志仅显示资源的当前状态,不包含等待或运行对象在资源上的任何计数或其他信息。
监视器:
监视器通过与对该对象感兴趣的线程进行通信,要求它们获取访问权限或等待某些条件成为真来同步访问对象。
例如: