Java synchronized修饰符
引言
在多线程编程中,为了保证共享资源的正确访问,我们需要使用同步机制来控制多个线程的执行顺序和互斥访问。Java提供了synchronized修饰符来实现同步,通过对代码块或方法进行同步,可以确保在同一时间只有一个线程访问被同步的代码。
本文将介绍Java中synchronized修饰符的使用方法,包括使用synchronized修饰代码块和方法,以及synchronized的实现原理。
流程图
st=>start: 开始
op1=>operation: 获取锁
op2=>operation: 执行同步代码
op3=>operation: 释放锁
e=>end: 结束
st->op1->op2->op3->e
使用synchronized修饰代码块
使用synchronized修饰代码块可以实现对指定对象的同步访问。以下是使用synchronized修饰代码块的步骤:
步骤 | 代码 | 描述 |
---|---|---|
1 | synchronized (obj) { |
使用synchronized关键字后面跟着小括号,括号中是要进行同步的对象 |
2 | // 同步代码 |
在代码块中编写需要同步执行的代码 |
3 | } |
代码块结束 |
下面是一个示例,展示了如何使用synchronized修饰代码块:
class MyClass {
private Object lock = new Object();
public void synchronizedMethod() {
synchronized (lock) { // 步骤1
// 同步代码,例如对共享资源进行访问
// ...
} // 步骤3
}
}
在上面的示例中,我们创建了一个私有对象lock作为同步锁。在synchronized代码块中,对lock对象进行了同步操作。只有获取到lock对象的线程才能执行代码块中的代码,其他线程将被阻塞,直到获取到lock对象。
使用synchronized修饰方法
除了可以使用synchronized修饰代码块外,还可以使用synchronized修饰方法来实现同步。使用synchronized修饰方法可以确保整个方法在同一时间只有一个线程执行。
使用synchronized修饰方法的步骤如下:
步骤 | 代码 | 描述 |
---|---|---|
1 | public synchronized void methodName() { |
在方法声明中添加synchronized关键字 |
2 | // 同步代码 |
在方法中编写需要同步执行的代码 |
3 | } |
方法结束 |
下面是一个示例,展示了如何使用synchronized修饰方法:
class MyClass {
public synchronized void synchronizedMethod() { // 步骤1
// 同步代码,例如对共享资源进行访问
// ...
} // 步骤3
}
在上面的示例中,我们将synchronized关键字添加到了方法声明中,从而实现了对整个方法的同步。只有获取到synchronizedMethod方法的线程才能执行该方法中的代码,其他线程将被阻塞,直到获取到该方法。
synchronized的实现原理
Java中的synchronized关键字的实现是基于对象的监视器锁(monitor),每个对象都有一个与之相关联的监视器锁。
当线程进入一个synchronized代码块或方法时,它将尝试获取对象的监视器锁。如果该锁已被其他线程获取,则线程将被阻塞,直到获取到监视器锁。一旦线程持有了监视器锁,它就可以执行同步代码,直到离开synchronized代码块或方法,然后释放监视器锁。
Java中的每个对象都有一个与之关联的锁标记(lock),用于存储关于锁的信息。锁标记可以是偏向锁、轻量级锁或重量级锁。根据锁的状态,JVM