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
我想找到一种方法来防止当我调用synchronizedMethod1时method1()运行。除非我弄错了所有方法都被调用,并且Java在运行时期间和之前编译它们,无论它是否同步。
我是否应该使用Lock对象和/或不使method1()成为同步方法?
答案 0 :(得分:1)
我想在我调用synchronizedMethod1
时找到一种方法来防止method1()运行
最简单的方法是让method1()
也成为synchronized
。这意味着两种方法都会导致他们正在调用的Common
实例上的锁定。只有一个线程可以调用synchronizedMethod1()
或method1()
。
除非我弄错了所有方法都被调用,并且Java在运行期间和之前编译它们,无论它是否已同步。
我不明白这个问题。您真的不必担心JVM的编译或优化阶段。
我应该使用Lock对象吗?
通常认为方法synchronized
不如使用private final
锁定对象。锁定对象只允许您在锁中更精细。例如,通过方法锁定,日志消息和其他不需要保护的语句也将是synchronized
。但如果目标是锁定整个方法,那么同步方法就没问题了。
答案 1 :(得分:0)
如果您希望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();
}
}
}