死磕synchronized

Rothschil 2020-05-14 15:53:00
Java

Synchronized,这是我接触Java多线程第一个关键字,现在回过头去看,它就是傻大黑,而且当初它效率还低,这就是我对他的第一印象。

这要通过一个样例来说明。定义一个Class类的一个同步方法,具体如下

1
2
3
4
5
6
7
8
9
10
11
12

public synchronized void setValue(int condition){
if(condition>0){
result=100;
System.out.println(Thread.currentThread().getName()+" A Set Value!!!!");
} else {
result=200;
System.out.println(Thread.currentThread().getName()+" B Set Value!!!!");
}

System.out.println(Thread.currentThread().getName()+" The Value is "+ result);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) {
MultiThread multiThread1 = new MultiThread();
MultiThread multiThread2 = new MultiThread();

Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
multiThread1.setValue(1);
}
});

Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
multiThread2.setValue(0);
}
});

t1.start();
t2.start();
}
1
2
3
4
Thread-0 A Set Value!!!!
Thread-1 B Set Value!!!!
Thread-1 The Value is 200
Thread-0 The Value is 100

这并不是我们想象的,线程T1执行完之后再执行T2,而且同时执行,说明我们同步代码块没有约束到。

原因分析: synchronized 取得的锁都是对象锁,而不是把一段代码(方法)当作锁,所以上面例子中的哪个线程先执行synchronized 关键字的方法,谁就有该方法所属对象的锁。因为实例出来的是两个对象,所以是两把锁,他们相互不影响。

有一种情况很特殊,就是类锁,即在静态方法加 synchronized ,表示 锁定.class,类一级别的锁,(独占 .class 类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14

private static int result;

public static synchronized void setValue(int condition){
if(condition>0){
result=100;
System.out.println(Thread.currentThread().getName()+" A Set Value!!!!");
} else {
result=200;
System.out.println(Thread.currentThread().getName()+" B Set Value!!!!");
}

System.out.println(Thread.currentThread().getName()+" The Value is "+ result);
}

输出内容如下:

1
2
3
4
Thread-0 A Set Value!!!!
Thread-0 The Value is 100
Thread-1 B Set Value!!!!
Thread-1 The Value is 200

分析这结果:T1 -> T2 ;这结果就是我们想要的。