Java 关键字 synchronized 总结

本文详细介绍了在Android开发中使用synchronized关键字实现线程同步的方法,包括如何通过对象锁和类锁来避免多线程访问同一资源时产生的冲突,并列举了各种应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#Android 学习计划#
#第一周#

存在的问题

同一进程的多个线程共享同一片存储空间,因此当多个线程同时访问同一个数据时,会造成访问冲突。

synchronized 类型

  • 修饰普通函数
public synchronized void start() {
    // do sth
}
  • 修饰静态函数
public static synchronized void start() {
    // do sth
}
  • 修饰代码块
// 普通函数
public void start() {
    synchronized(this) {
        // do sth
    }
}
// 静态函数
public static void start() {
    synchronized(Foo.class) {
        // do sth
    }
}

其中,第一段代码与第三段代码等价,第二段代码与第四段代码等价。

访问 synchronized 函数/代码段时,拿到的是什么?

  • 普通函数:该对象的锁
  • 静态函数:该类的锁

synchronized 基本原理

在一个线程访问 synchronized 函数/代码段,拿到该对象/类的锁后,在该函数/代码段执行完之前,其他线程访问相同的对象/类中的 synchronized 函数/代码段(不一定是相同的函数/代码段),会进入阻塞状态,直到前一个线程执行完函数/代码段为止,从而实现线程同步。

下面分6种情况说明该问题:

  • synchronized 修饰普通函数 a(),两个线程同时访问同一个对象的 a(),线程同步:
A a1 = new A();

Thread1
a1.a();

Thread2
a1.a();
  • synchronized 修饰普通函数 a(),两个线程同时访问(同一个类的)多个对象的 a(),线程不同步:
A a1 = new A();
A a2 = new A();

Thread1
a1.a();

Thread2
a2.a();
  • synchronized 修饰普通函数 a() 和 b(),两个线程分别同时访问同一个对象的 a() 和 b(),线程同步:
A a1 = new A();

Thread1
a1.a();

Thread2
a1.b();
  • synchronized 修饰静态函数 a(),两个线程同时访问同一个类的 a(),线程同步:
Thread1
A.a();

Thread2
A.a();
  • synchronized 修饰静态函数 a() 和 b(),两个线程分别同时访问同一个类的 a() 和 b(),线程同步:
Thread1
A.a();

Thread2
A.b();
  • synchronized 修饰普通函数 a() 和静态函数 b(),两个线程分别同时访问一个对象的 a() 和一个类的 b(),线程不同步(锁的类型不同):
A a1 = new A();

Thread1
a1.a();

Thread2
A.b();

synchronized 修饰代码块,根据代码块所处函数类型的不同,可以在上述6种情况中找到等价的情况。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值