synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
package
com.fyb.concurrent;
public
class
SynchronizedTest {
private
int
num;
public
synchronized
void
method01(String arg) {
try
{
if
(
"a"
.equals(arg)){
num =
100
;
System.out.println(
"tag a set number over"
);
Thread.sleep(
1000
);
}
else
{
num =
200
;
System.out.println(
"tag b set number over"
);
}
System.out.println(
"tag = "
+ arg +
";num ="
+ num);
}
catch
(InterruptedException e) {
e.printStackTrace();
}
}
public
static
void
main(String[] args) {
final
SynchronizedTest m1 =
new
SynchronizedTest();
final
SynchronizedTest m2 =
new
SynchronizedTest();
Thread t1 =
new
Thread(
new
Runnable() {
@Override
public
void
run() {
m1.method01(
"a"
);
}
});
t1.start();
Thread t2 =
new
Thread(
new
Runnable() {
@Override
public
void
run() {
m2.method01(
"b"
);
}
});
t2.start();
}
}
|
执行输出:
1
2
3
4
|
tag a set number over
tag b set number over
tag = b;num =200
tag = a;num =100
|
可以看出,两个不同的对象m1和m2的method01()方法执行并没有互斥,因为这里synchronized是分别持有两个对象的锁。如果要想m1,m2两个对象竞争同一个锁,则需要在method01()上加上static修饰。如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
package
com.fyb.concurrent;
public
class
SynchronizedTest {
private
static
int
num;
public
static
synchronized
void
method01(String arg) {
try
{
if
(
"a"
.equals(arg)){
num =
100
;
System.out.println(
"tag a set number over"
);
Thread.sleep(
1000
);
}
else
{
num =
200
;
System.out.println(
"tag b set number over"
);
}
System.out.println(
"tag = "
+ arg +
";num ="
+ num);
}
catch
(InterruptedException e) {
e.printStackTrace();
}
}
public
static
void
main(String[] args) {
final
SynchronizedTest m1 =
new
SynchronizedTest();
final
SynchronizedTest m2 =
new
SynchronizedTest();
Thread t1 =
new
Thread(
new
Runnable() {
@Override
public
void
run() {
m1.method01(
"a"
);
}
});
t1.start();
Thread t2 =
new
Thread(
new
Runnable() {
@Override
public
void
run() {
m2.method01(
"b"
);
}
});
t2.start();
}
}
|
输出结果:
1
2
3
4
|
tag a set number over
tag = a;num =100
tag b set number over
tag = b;num =200
|
小结:
synchronized修饰不加static的方法,锁是加在单个对象上,不同的对象没有竞争关系;修饰加了static的方法,锁是加载类上,这个类所有的对象竞争一把锁。