Java 关键字 synchronized 总结

来源:互联网 发布:telnet 端口 编辑:程序博客网 时间:2024/05/17 22:02

# 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();Thread1a1.a();Thread2a1.a();
  • synchronized 修饰普通函数 a(),两个线程同时访问(同一个类的)多个对象的 a(),线程不同步:
A a1 = new A();A a2 = new A();Thread1a1.a();Thread2a2.a();
  • synchronized 修饰普通函数 a() 和 b(),两个线程分别同时访问同一个对象的 a() 和 b(),线程同步:
A a1 = new A();Thread1a1.a();Thread2a1.b();
  • synchronized 修饰静态函数 a(),两个线程同时访问同一个类的 a(),线程同步:
Thread1A.a();Thread2A.a();
  • synchronized 修饰静态函数 a() 和 b(),两个线程分别同时访问同一个类的 a() 和 b(),线程同步:
Thread1A.a();Thread2A.b();
  • synchronized 修饰普通函数 a() 和静态函数 b(),两个线程分别同时访问一个对象的 a() 和一个类的 b(),线程不同步(锁的类型不同):
A a1 = new A();Thread1a1.a();Thread2A.b();

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

原创粉丝点击