xde*_*000 115 java concurrency multithreading monitor
什么是Java中并发编程中引用的监视器?
当我读到"每个对象都有一个监视器"这是什么意思?
这是一个特殊的对象吗?
Pab*_*ruz 80
监视器是控制对象的并发访问的机制.
这允许你这样做:
线程1:
public void a()
{
synchronized(someObject) {
// do something (1)
}
}
Run Code Online (Sandbox Code Playgroud)
线程2:
public void b()
{
synchronized(someObject) {
// do something else (2)
}
}
Run Code Online (Sandbox Code Playgroud)
这可以防止线程1和2同时访问受监视(同步)部分.一个将开始,监视器将阻止另一个在第一个完成之前访问该区域.
这不是一个特殊的对象.它的同步机制放在类层次结构根目录:java.lang.Object.
也有wait和notify,也将使用对象的监视器通信不同的线程之间的方法.
JRL*_*JRL 24
监视器是拥有锁定和等待集合的实体.在Java中,任何Object可以充当监视器.
有关监视器如何在Java中工作的详细说明,我建议阅读Java中的Concurrent Programming的Monitor Mechanics部分(上面的链接显示了Google书籍中的预览,该部分可供阅读).
在并发编程中,我们需要关注两件事
当进程/线程正在执行其临界区时,不允许其他进程执行其临界区。(每个进程都有一个称为“临界区”的代码段,其中访问共享数据。)
当线程试图通过协同工作来实现一个共同的目标时,这些线程需要它们之间的合作。当他们专注于一个共同的目标时,他们需要同步。
监视器用于实现互斥和同步。
不要将此临界区与临界区混淆,因为这里提到的临界区是对象级的,而不是线程级的。共享数据被视为关键区域。
每个对象及其类都与一个监视器相关联。需要防止并发访问的对象的实例变量包括与对象关联的监视器的关键区域和需要防止并发访问的类的实例变量/类的静态变量包括在关键区域中与类关联的监视器。
这个关键区域用锁保护,这个锁确保互斥。
等待集还与用于在线程之间提供协调的监视器相关联。
一个条目集用于保存已经请求锁定并且尚未获得锁定的线程。
每个对象都与一个监视器相关联,并且这个监视器有一个锁,每个线程在访问共享变量时可以使用这个锁来锁定或解锁对象。明确地,这意味着一次只有一个线程可以持有监视器上的锁。任何其他试图锁定该锁的线程都将被阻塞,直到它们能够获得该锁. 当一个新线程尝试获取锁并且如果已经有一个线程拥有该锁,则该线程将等待条目集以获取该锁。当获得锁的线程完成其临界区时,它将释放锁。因此,下一个线程将获取锁,但下一个线程是从条目集中获取的,并将由 JVM 根据某些标准(如 FIFO)确定。
在这里,我们实现了互斥,因为我们为对象提供了对线程的独占访问权限,并且不允许任何其他线程进入它们的临界区。
使用监视器实现互斥的示例java代码
class Counter
{
private int count = 0;
public void synchronized Increment() {
int n = count;
count = n+1;
} //Here synchronized is used to indicate those things should be done sequentially.
}
Run Code Online (Sandbox Code Playgroud)
使用与监视器相关联的等待集和“等待并通知”或“信号并继续”机制来实现同步。 当一个线程需要一些数据处于特定状态而另一个线程负责将数据进入该状态(例如生产者/消费者问题)时,同步很重要
当线程调用针对对象的 wait() 方法时,该线程将挂起并添加到等待集以等待其他线程对同一对象调用 notify() 或 notifyAll() 。
notify() 方法用于唤醒处于特定对象监视器的等待集中的线程。有两种通知等待线程的方法。
在生产者消费者问题中使用监视器实现同步的示例 Java 代码
class Buffer {
private char [] buffer;
private int count = 0, in = 0, out = 0;
Buffer(int size)
{
buffer = new char[size];
}
public synchronized void Put(char c) {
while(count == buffer.length)
{
try { wait(); }
catch (InterruptedException e) { }
finally { }
}
System.out.println("Producing " + c + " ...");
buffer[in] = c;
in = (in + 1) % buffer.length;
count++;
notify();
}
public synchronized char Get() {
while (count == 0)
{
try { wait(); }
catch (InterruptedException e) { }
finally { }
}
char c = buffer[out];
out = (out + 1) % buffer.length;
count--;
System.out.println("Consuming " + c + " ...");
notify();
return c;
}
}
Run Code Online (Sandbox Code Playgroud)
请参阅以下链接 http://www.csc.villanova.edu/~mdamian/threads/javamonitors.html#:~:text=Java%20associates%20a%20monitor%20with,the%20monitor%20for%20that%20object https: //howtodoinjava.com/java/multi-threading/how-to-use-locks-in-java-java-util-concurrent-locks-lock-tutorial-and-example/
| 归档时间: |
|
| 查看次数: |
70380 次 |
| 最近记录: |