【发布时间】:2017-04-02 15:22:23
【问题描述】:
我现在正在学习 Java 并发。我遇到了这样一段代码:
package pac1;
import java.util.*;
import java.util.concurrent.*;
class A1 {
public void f() {
synchronized (this) {
for (int i = 0; i < 5; i++)
System.out.println("f()");
}
}
}
class B1 {
public void g() {
synchronized (this) {
for (int i = 0; i < 5; i++)
System.out.println("g()");
}
}
}
class C1 {
public void p() {
synchronized (this) {
for (int i = 0; i < 5; i++)
System.out.println("p()");
}
}
}
public class V {
public static void main(String[] args) {
A1 a = new A1();
B1 b = new B1();
C1 c = new C1();
new Thread() {
public void run() {
a.f();
}
}.start();
new Thread() {
public void run() {
c.p();
}
}.start();
b.g();
}
}
由于这段代码使用不同的对象来调用同步方法,我认为它不会阻止它们相互干扰。但是,结果如下:
f()
f()
f()
f()
f()
g()
g()
g()
g()
g()
p()
p()
p()
p()
p()
顺便说一句,使用Lock的结果是一样的:
package pac1;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class A {
Lock lock = new ReentrantLock();
public void f() {
lock.lock();
try {
for (int i = 0; i < 5; i++)
System.out.println("f()");
} finally {
lock.unlock();
}
}
}
class B {
Lock lock = new ReentrantLock();
public void g() {
lock.lock();
try {
for (int i = 0; i < 5; i++)
System.out.println("g()");
} finally {
lock.unlock();
}
}
}
class C {
Lock lock = new ReentrantLock();
public void p() {
lock.lock();
try {
for (int i = 0; i < 5; i++)
System.out.println("p()");
} finally {
lock.unlock();
}
}
}
public class Ex16 {
public static void main(String[] args) {
A a = new A();
B b = new B();
C c = new C();
new Thread() {
public void run() {
a.f();
}
}.start();
new Thread() {
public void run() {
c.p();
}
}.start();
b.g();
}
}
【问题讨论】:
-
尝试打印更多内容。我怀疑Java在设置第二个线程的方法时完成了第一个线程的方法,然后在那个真正开始之前它已经完成了main方法的运行,所以你可以按1、3、2的顺序打印它们。我敢打赌,如果你每个都做 1000 个,他们就会搞混了。
-
是什么让您认为它们相互干扰?在每次迭代时添加对 Thread.sleep(500) 的调用。
标签: java concurrency thread-safety synchronized