public class Common {
public synchronized void synchronizedMethod1() {
System.out.println("synchronizedMethod1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synchronizedMethod1 done");
}
public void method1() {
System.out.println("Method 1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Method 1 done");
}
}
public class MyThread extends Thread {
private int id = 0;
private Common common;
public MyThread(String name, int no, Common object) {
super(name);
common = object;
id = no;
}
public void run() {
System.out.println("Running Thread" + this.getName());
try {
if (id == 0) {
common.synchronizedMethod1();
} else {
common.method1();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Common c = new Common();
MyThread t1 = new MyThread("MyThread-1", 0, c);
MyThread t2 = new MyThread("MyThread-2", 1, c);
t1.start();
t2.start();
}
}
输出:
Running ThreadMyThread-1
synchronizedMethod1 called
Running ThreadMyThread-2
Method 1 called
synchronizedMethod1 done
Method 1 done
我想找到一种方法来防止method1((在我调用syncdMethod1时运行。除非我弄错了,否则所有方法都被调用,Java 会在运行时和运行时之前编译它们,无论它是否同步。
我应该使用 Lock 对象代替和/或不也使 method1(( 成为同步方法吗?
我想找到一种方法来防止method1((在调用syncdMethod1时运行
最简单的方法是使method1()
也synchronized
。 这意味着这两种方法都会导致它们正在调用的Common
实例被锁定。 只有一个线程可以调用synchronizedMethod1()
或method1()
。
除非我弄错了,否则所有方法都被调用,Java 会在运行时和运行时之前编译它们,无论它是否同步。
我不明白这个问题。 您真的不必担心 JVM 的编译或优化阶段。
我应该改用 Lock 对象吗?
通常,使方法synchronized
被认为不如使用private final
锁定对象。 锁定对象只是允许您在锁中更细粒度。 例如,使用方法锁定,日志消息和其他不需要保护的语句也将synchronized
。 但是,如果目标是锁定整个方法,则可以同步方法。
如果您希望method1
和synchronizedMethod1
相互排斥,则需要使用相同的锁来保护它们。无论是使用 Lock
还是简单地在同一 Object 实例上调用synchronize
,结果都大致相同。
如果您希望允许多个线程执行method1
但不是在调用synchronizedMethod1
时执行,则需要一个ReadWriteLock
来完成此操作。
public class Common {
ReadWriteLock rwLock = new ReentrantReadWriteLock();
public void synchronizedMethod1() {
rwLock.writeLock().lock();
try {
System.out.println("synchronizedMethod1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("synchronizedMethod1 done");
} finally {
rwLock.writeLock().unlock();
}
}
public void method1() {
rwLock.readLock().lock();
try {
System.out.println("Method 1 called");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Method 1 done");
} finally {
rwLock.readLock().unlock();
}
}
}