博文目录
- synchronized 基础
- 对象监视器 Monitor
- synchronized 的使用方式
synchronized 基础
synchronized详解
在 JDK1.5 之前, synchronized 是一个重量级锁, 频繁加解锁 *** 作相对来说比较影响性能. JDK 6 官⽅从 JVM 层⾯对 synchronized 进行了⼤优化, 大幅提升了其运行效率. 现在的 synchronized 可以说非常高效, 在较为简单的场景完全可以替代 Lock
对象监视器 Monitor synchronized 的使用方式synchronized 可以修饰静态方法, 也可以修饰实例方法, 也可以修饰代码块. 不管哪种方式, 都要明确 synchronized 的作用对象
不论使用 synchronized 的哪种方式, 只要有一个线程抢到了某一个对象的锁, 则争抢该对象锁的其他线程将阻塞等待, 直到该线程释放锁, 其他线程将被唤醒开启新一轮的争抢
举例: 不同线程同时运行下面的方法时, 线程彼此间会相互竞争锁, 因为他们都是对 SynchronizedTest.class 对象加锁
- SynchronizedTest::foo, 修饰静态方法
- SynchronizedTest::a, 修饰静态方法中的代码块
- object1::e, 修饰动态方法中的代码块
- object2::e, 修饰动态方法中的代码块
package jdk.java.util.concurrent.locks;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
@Slf4j
public class SynchronizedTest {
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
public static synchronized void foo() {
// 修饰静态方法, SynchronizedTest.class
sleep();
log.info("SynchronizedTest.class, foo, static, method");
}
public synchronized void bar() {
// 修饰动态方法, this, 就是调用 e 方法的那个实例对象
sleep();
log.info("this, bar, dynamic, method");
}
public static void a() {
synchronized (SynchronizedTest.class) {
// 修饰代码块, SynchronizedTest.class
sleep();
log.info("SynchronizedTest.class, a, static, code block");
}
}
public static void b() {
synchronized (lock1) {
// 修饰代码块, lock1
sleep();
log.info("lock1, b, static, code block");
}
}
public static void c() {
synchronized (lock2) {
// 修饰代码块, lock2
sleep();
log.info("lock2, c, static, code block");
}
}
public void d() {
synchronized (this) {
// 修饰代码块, this, 就是调用 e 方法的那个实例对象
sleep();
log.info("this, d, dynamic, code block");
}
}
public void e() {
synchronized (SynchronizedTest.class) {
// 修饰代码块, SynchronizedTest.class
sleep();
log.info("SynchronizedTest.class, e, dynamic, code block");
}
}
public void f() {
synchronized (lock1) {
// 修饰代码块, lock1
sleep();
log.info("lock1, f, dynamic, code block");
}
}
public void g() {
synchronized (lock2) {
// 修饰代码块, lock2
sleep();
log.info("lock2, g, dynamic, code block");
}
}
private static void sleep() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (Throwable cause) {
cause.printStackTrace();
}
}
public static void main(String[] args) {
SynchronizedTest object1 = new SynchronizedTest();
SynchronizedTest object2 = new SynchronizedTest();
try {
// SynchronizedTest.class
// new Thread(SynchronizedTest::foo, "SynchronizedTest::foo").start();
// new Thread(SynchronizedTest::a, "SynchronizedTest::a").start();
// new Thread(object1::e, "object1::e").start();
// new Thread(object2::e, "object2::e").start();
//[20220427.163648.034][INFO ][SynchronizedTest::foo] SynchronizedTest.class, foo, static, method
//[20220427.163649.037][INFO ][object2::e ] SynchronizedTest.class, e, dynamic, code block
//[20220427.163650.040][INFO ][object1::e ] SynchronizedTest.class, e, dynamic, code block
//[20220427.163651.054][INFO ][SynchronizedTest::a ] SynchronizedTest.class, a, static, code block
// this (object1)
// new Thread(object1::bar, "object1::bar").start();
// new Thread(object1::d, "object1::d").start();
//[20220427.163734.814][INFO ][object1::bar ] this, bar, dynamic, method
//[20220427.163735.826][INFO ][object1::d ] this, d, dynamic, code block
// this (object2)
// new Thread(object2::bar, "object2::bar").start();
// new Thread(object2::d, "object2::d").start();
//[20220427.163751.118][INFO ][object2::bar ] this, bar, dynamic, method
//[20220427.163752.129][INFO ][object2::d ] this, d, dynamic, code block
// lock1
// new Thread(SynchronizedTest::b, "SynchronizedTest::b").start();
// new Thread(object1::f, "object1::f").start();
// new Thread(object2::f, "object2::f").start();
//[20220427.163811.036][INFO ][SynchronizedTest::b ] lock1, b, static, code block
//[20220427.163812.050][INFO ][object2::f ] lock1, f, dynamic, code block
//[20220427.163813.064][INFO ][object1::f ] lock1, f, dynamic, code block
// lock2
// new Thread(SynchronizedTest::c, "SynchronizedTest::c").start();
// new Thread(object1::g, "object1::g").start();
// new Thread(object2::g, "object2::g").start();
//[20220427.163835.506][INFO ][SynchronizedTest::c ] lock2, c, static, code block
//[20220427.163836.516][INFO ][object2::g ] lock2, g, dynamic, code block
//[20220427.163837.530][INFO ][object1::g ] lock2, g, dynamic, code block
// SynchronizedTest.class, object1, object2, lock1, lock2 混搭
// SynchronizedTest.class
new Thread(SynchronizedTest::foo, "SynchronizedTest::foo").start();
new Thread(SynchronizedTest::a, "SynchronizedTest::a").start();
new Thread(object1::e, "object1::e").start();
new Thread(object2::e, "object2::e").start();
// object1
new Thread(object1::bar, "object1::bar").start();
new Thread(object1::d, "object1::d").start();
// object2
new Thread(object2::bar, "object2::bar").start();
new Thread(object2::d, "object2::d").start();
// lock1
new Thread(SynchronizedTest::b, "SynchronizedTest::b").start();
new Thread(object1::f, "object1::f").start();
new Thread(object2::f, "object2::f").start();
// lock2
new Thread(SynchronizedTest::c, "SynchronizedTest::c").start();
new Thread(object1::g, "object1::g").start();
new Thread(object2::g, "object2::g").start();
//[20220427.163903.295][INFO ][SynchronizedTest::b ] lock1, b, static, code block
//[20220427.163903.295][INFO ][SynchronizedTest::foo] SynchronizedTest.class, foo, static, method
//[20220427.163903.295][INFO ][SynchronizedTest::c ] lock2, c, static, code block
//[20220427.163903.295][INFO ][object1::bar ] this, bar, dynamic, method
//[20220427.163903.295][INFO ][object2::bar ] this, bar, dynamic, method
//[20220427.163904.305][INFO ][object2::g ] lock2, g, dynamic, code block
//[20220427.163904.305][INFO ][object2::f ] lock1, f, dynamic, code block
//[20220427.163904.305][INFO ][object2::d ] this, d, dynamic, code block
//[20220427.163904.305][INFO ][object1::d ] this, d, dynamic, code block
//[20220427.163904.305][INFO ][object2::e ] SynchronizedTest.class, e, dynamic, code block
//[20220427.163905.313][INFO ][object1::f ] lock1, f, dynamic, code block
//[20220427.163905.313][INFO ][object1::g ] lock2, g, dynamic, code block
//[20220427.163905.313][INFO ][object1::e ] SynchronizedTest.class, e, dynamic, code block
//[20220427.163906.316][INFO ][SynchronizedTest::a ] SynchronizedTest.class, a, static, code block
TimeUnit.SECONDS.sleep(5);
System.out.println();
} catch (Throwable cause) {
cause.printStackTrace();
}
}
}
- synchronized 静态方法: 本类.class
- synchronized 静态代码块:
- 本类.class:
- 某 object:
- synchronized 动态方法: this
- synchronized 动态代码块:
- this:
- 某 object:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)