Android 同步锁 synchronized,归根到底还是java同步锁问题。下边看一个例子:
public class Syn {
public synchronized void start(){
System.out.println("吃饭...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("睡觉...打豆豆");
}
}
public class TestSyn {
static class TestThread extends Thread{
public TestThread() {
}
@Override
public void run() {
Syn syn = new Syn();
syn.start();
}
}
public static void main(String[] args){
for (int i = 0; i <4; i++) {
TestThread t = new TestThread();
t.start();
}
}
}
吃饭、睡觉、打豆豆这是一个流程。多线程操作,加上同步锁synchronized ,我们看一下结果:
同步1.png
同步1.png
我们就纳闷了,为什么线程不是吃饭、睡觉、打豆豆这样一个流程走完。
Synchronized 不是同步代码块吗?我们试着调整一下代码:
public class Syn {
public void start(){
synchronized(this){
System.out.println("吃饭...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("睡觉...打豆豆");
}
}
}
结果:
同步2.png
很明显, synchronized(this) 同步代码块和 synchronized 同步方法的效果是一样的。那么怎么才能使每个线程都是执行完吃饭、睡觉、打豆豆这样一个流程再执行下一个线程。很明显因为4个线程,new 了四个对象。synchronized(this) 同步代码块和 synchronized 同步方法 针对的是synchronized括号里边的,即this对象。所以:
package com.lqg.asynchronized;
/**
* Created by Administrator on 2017/8/13.
*/
public class TestSyn {
static class TestThread extends Thread{
private Syn mSyn;
public TestThread(Syn syn) {
mSyn = syn;
}
@Override
public void run() {
mSyn.start();
}
}
public static void main(String[] args){
Syn syn = new Syn();
for (int i = 0; i <4; i++) {
TestThread t = new TestThread(syn);
t.start();
}
}
}
只创建同一个对象,结果:
同步3.png
看出来线程同步起到作用了。但是如果是多个对象创建,线程同步又得怎么处理呢?
public class Syn {
public static synchronized void start(){
System.out.println("吃饭...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("睡觉...打豆豆");
}
}
public class TestSyn {
static class TestThread extends Thread{
public TestThread() {
}
@Override
public void run() {
Syn syn = new Syn();
syn.start();
}
}
public static void main(String[] args){
for (int i = 0; i <4; i++) {
TestThread t = new TestThread();
t.start();
}
}
}
同步四.png
和一开始的区别只在于public static synchronized void start() 只加个静态方法,可见同步静态方法相当于同步Syn 这个类。也可以这样写:
public static void start(){
synchronized(Syn.class){
......
}
}
总结:
1、非静态方法的同步锁只对同一个对象有效。对不同对象起不到同步的作用。
2、静态方法同步锁锁的是类,锁是整个类对象的锁,这个对象是就是这个类(XXX.class)。
3、关于锁的范围,能锁住代码块的范围就就尽量不要锁方法。比较加锁之后,要等待其他线程执行完,相对比较耗时。