#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种情况中找到等价的情况。