[英]Thread calling non-synchronized instance method when a synchronized method is called
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
我想找到一种方法来防止在我调用syncedMethod1时method1()运行。 除非我没有记错,否则所有方法都将被调用,并且Java在运行时以及运行时进行编译,无论是否同步。
我应该使用Lock对象代替和/或也不要使method1()成为同步方法吗?
我想找到一种方法来防止在我调用syncedMethod1时method1()运行
最简单的方法是使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();
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.