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、關于鎖的范圍,能鎖住代碼塊的范圍就就盡量不要鎖方法。比較加鎖之后,要等待其他線程執行完,相對比較耗時。