package test;
public class Test2 {
static class Inner1 {
public void m1() {
synchronized("aaaa") {
for (char c = 'a'; c <= 'g'; c++) {
System.out.println(Thread.currentThread().getName() + " m1() : " + c);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
public synchronized void m2() {
for (char c = 'a'; c <= 'g'; c++) {
System.out.println(Thread.currentThread().getName() + " m2() : " + c);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
}
public static void main(String[] args) {
final Inner1 in1 = new Inner1();
Thread t1 = new Thread(
new Runnable() {
public void run() {
in1.m1();
}
}, "T1"
);
Thread t2 = new Thread(
new Runnable() {
public void run() {
in1.m2();
}
}, "T2"
);
t1.start();
t2.start();
}
}
结果:
T1 m1() : a
T2 m2() : a
T1 m1() : b
T2 m2() : b
T1 m1() : c
T2 m2() : c
T1 m1() : d
T2 m2() : d
T1 m1() : e
T2 m2() : e
T1 m1() : f
T2 m2() : f
T1 m1() : g
T2 m2() : g
分析:
m2()是Inner1类中的一个同步方法,而m1()中包含了一个同步块。
m1()中的同步块只是针对对象"aaaa"进行同步,它不能对Inner1实例本身进行同步。所以,如上例所示,两个线程互不干扰,同时运行。
再看下面这个例子:
package test;
public class Test1 {
static class Inner1 {
public void m1(Inner2 i2) {
String str = Thread.currentThread().getName();
synchronized (i2) {
System.out.println(str + " enter: Inner1.m1()");
for (char c = 'a'; c <= 'g'; c++) {
System.out.println(str + "goto: " + c);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
System.out.println(str + " leave: Inner1.m1()");
}
}
public synchronized void m2() {
String str = Thread.currentThread().getName();
System.out.println(str + " enter: Inner1.m2()");
for (char c = 'a'; c <= 'z'; c++) {
System.out.println(str + "goto: " + c);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
System.out.println(str + " leave: Inner1.m2()");
}
}
static class Inner2 {
public synchronized void m1() {
String str = Thread.currentThread().getName();
System.out.println(str + " enter: Inner2.m1()");
for (char c = 'a'; c <= 'g'; c++) {
System.out.println(str + "goto: " + c);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
System.out.println(str + " leave: Inner2.m1()");
}
}
public static void main(String[] args) {
final Inner1 in1 = new Inner1();
final Inner2 in2 = new Inner2();
Thread t1 = new Thread(
new Runnable() {
public void run() {
in1.m1(in2);
}
}, "T1"
);
Thread t2 = new Thread(
new Runnable() {
public void run() {
in1.m2();
}
}, "T2"
);
Thread t3 = new Thread(
new Runnable() {
public void run() {
in2.m1();
}
}, "T3"
);
t1.start();
t2.start();
t3.start();
}
}
结果:
T1 enter: Inner1.m1()
T1goto: a
T2 enter: Inner1.m2()
T2goto: a
T1goto: b
T2goto: b
T1goto: c
T2goto: c
T1goto: d
T2goto: d
T1goto: e
T2goto: e
T2goto: f
T1goto: f
T2goto: g
T1goto: g
T2goto: h
T1 leave: Inner1.m1()
T3 enter: Inner2.m1()
T3goto: a
T2goto: i
T3goto: b
T3goto: c
T2goto: j
T3goto: d
T2goto: k
T3goto: e
T2goto: l
T3goto: f
T2goto: m
T3goto: g
T2goto: n
T3 leave: Inner2.m1()
T2goto: o
T2goto: p
T2goto: q
T2goto: r
T2goto: s
T2goto: t
T2goto: u
T2goto: v
T2goto: w
T2goto: x
T2goto: y
T2goto: z
T2 leave: Inner1.m2()
分析:
T2的执行贯穿整个过程。T3在T1结束对Inner1.m1()的调用后才调用Inner2.m1(),这是因为Inner1.m1()方法中的同步块锁住了Inner2的对象in2。