我正在学习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()
BTW,结果与使用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();
}
}
答案 0 :(得分:1)
您不需要锁定或在此同步。 Sychronized用于锁定对共享可变状态的访问。您没有任何共享的可变状态。
这里有3个线程,没有人可以预测这些线程因上下文切换而运行的顺序。我没有看到问题。
答案 1 :(得分:0)
实际上循环不够长,因此允许线程以它们启动的相同顺序完成。为了表明线程不会干扰,您可以尝试以下方法之一:
让循环运行更长时间,例如1000次迭代应该足够了:
synchronized (this) {
for (int i = 0; i < 1000; i++)
System.out.println("f()");
}
挂起循环中的线程,但要确保为每个循环设置不同的间隔:
synchronized (this) {
for (int i = 0; i < 5; i++) {
System.out.println("p()");
try {
Thread.sleep(3000);
} catch (final InterruptedException ex) {
// Swallow
}
}
}
故事很长:这些锁实际上并没有干涉。