Java多线程并发之synchronized关键字、wait()、notify()与Monitor机制

synchronized、wait、notify结合使用,用于并发编程中防止多个线程对共享资源的访问导致数据不一致的问题。

synchronized关键字、wait()、notify()

Lock 和 Condition 接口为程序设计人员提供了高度的锁定控制。然而,大多数情况下,并不需要那样的控制,并且可以使用一种嵌人到 Java语言内部的机制。从 1.0 版开始,Java中的每一个对象都有一个内部锁。如果一个方法用 synchronized关键字声明,那么对象的内部锁将保护整个方法。也就是说,要调用该方法,线程必须获得对象的内部锁。
内部对象锁只有一个相关条件。wait 方法添加一个线程到等待集中,notifyAll/notify方法解除等待线程的阻塞状态。换句话说,调用 wait 等价于 condition.await() ,调用notityAll()等价于condition.singnalAll()。

wait、notifyAll 以及 notify 方法是 Object 类的 final 方法。Condition 方法必须被命名为 await、signalAll 和 signal 以便它们不会与那些方法发生冲突。

使用 synchronized 关键字来编写代码要比Lock/Condition简洁得多。当然,要理解这一代码,你必须了解Java的每一个对象都有一个内部锁, 并且该锁有一个内部条件。由锁来管理那些试图进入synchronized 方法的线程,由条件来管理那些调用 wait 的线程。

synchronized 关键字的原理就是Java对象的Monitor机制。

Java对象的Monitor机制

概述

Java虚拟机给每个对象和class字节码都设置了一个监听器Monitor,用于检测并发代码的重入,同时在Object类中还提供了notify()和wait()方法来对线程进行控制。
在java.lang.Object类中有如下代码:

public class Object {
	...
	private transient int shadow$_monitor_;
	public final native void notify();
	public final native void notifyAll();
	public final native void wait() throws InterruptedException;
	public final void wait(long millis) throws InterruptedException {
		wait(millis, 0);
	}
	public final native void wait(long millis, int nanos) throws InterruptedException;
	...
}

原理分析

Java 对象模型中,所有的对象头部都有锁状态标记。偏向锁,轻量锁,重量锁都在Mark Word中都有锁标记或锁的地址。
在这里插入图片描述

【转载】Java多线程(二)——Java对象的Monitor机制
synchronized、monitor、wait、notify

发布了516 篇原创文章 · 获赞 89 · 访问量 73万+

猜你喜欢

转载自blog.csdn.net/yzpbright/article/details/104644518