Java 从同步方法中调用方法
我面临一个奇怪的问题,这让我想知道在同步方法中到底发生了什么。假设有一种方法Java 从同步方法中调用方法,java,multithreading,concurrentmodification,Java,Multithreading,Concurrentmodification,我面临一个奇怪的问题,这让我想知道在同步方法中到底发生了什么。假设有一种方法 synchronized public void example(){ //...code int i=call(); //calling another method //...do something with i } 现在,在执行call()方法时,另一个对象可以进入这个同步的example()方法吗?因此,当call()返回时,可能会出现一些ConcurrentModifica
synchronized public void example(){
//...code
int i=call(); //calling another method
//...do something with i
}
现在,在执行call()方法时,另一个对象可以进入这个同步的example()方法吗?因此,当call()返回时,可能会出现一些ConcurrentModificationException?如何避免出现问题?不,不行。同步方法基本上与以下方法相同:
public void example(){
synchronized(this){
//do stuff
}
}
不,不能。同步方法基本上与以下方法相同:
public void example(){
synchronized(this){
//do stuff
}
}
当一个线程进入一个同步的方法时,会发生一个锁,该锁在该方法返回之前不会释放,而该方法将在您调用
call()
之后返回
下面是一篇关于锁和同步的好文章:
当线程进入一个同步的方法时,会发生锁,直到该方法返回,锁才会释放,这将发生在调用
call()
之后
下面是一篇关于锁和同步的好文章:
请注意,在本例中,如果
call()
不是私有的,或者是从类中的其他地方调用的,则其他人可以中断您认为完全同步的过程
synchronized void a(){
println 'hello'
b();
println 'world'
}
void b(){
}
如果您希望“a所做的一切都由synchronized保护”,那么如果b有任何副作用,那么如果
synchronized以外的方法使a
调用b
,无效,则该保证将丢失。请注意,在本例中,如果调用()
不是私有的,或者是从类中的其他地方调用的,其他人可以打断你认为是完全同步的过程
synchronized void a(){
println 'hello'
b();
println 'world'
}
void b(){
}
如果您希望“a所做的一切都由synchronized保护”,那么如果b有任何副作用,那么如果
synchronized以外的方法使a无效
调用b
,那么即使我离开synchronized方法,然后返回,它也会像一个完整的大型同步方法一样?调用外部方法不会导致任何问题?我之所以这么确定是因为,那么我的程序中的问题可能是因为其他原因,我必须找出原因。谢谢。不,它们不会导致任何问题。如果他们愿意,您可以在同步块中执行什么操作?任何有意义的任务都涉及调用某个方法。@aps即使该方法是同步的,实际发生的情况是在方法启动时输入调用对象上的监视器,然后在方法返回时退出。这两点之间发生的任何事情都不会影响监视器的状态,因此即使是外部方法也不会影响监视器的状态。因此,即使我离开同步方法,然后返回,它也会像一个完整的大型同步方法一样?调用外部方法不会导致任何问题?我之所以这么确定是因为,那么我的程序中的问题可能是因为其他原因,我必须找出原因。谢谢。不,它们不会导致任何问题。如果他们愿意,您可以在同步块中执行什么操作?任何有意义的任务都涉及调用某个方法。@aps即使该方法是同步的,实际发生的情况是在方法启动时输入调用对象上的监视器,然后在方法返回时退出。这两点之间发生的任何事情都不会影响监视器的状态,因此即使是外部方法也不会影响监视器的状态。我明白你的意思。那么在这种情况下我该怎么办?使b同步,这样就不会发生中断?如果只从a调用b
,您就没事了。为了安全起见,可以同步类中的任何入口点(public、protected、default)方法。这样,实际上可以保证一次只有一个线程可以使用该对象。另外,请确保不要直接操作公共、受保护或默认变量,因为您可以使用与方法设置完全相同的方法进行处理。有关此主题的详细说明,请参阅SCJP 6学习手册@格雷格:我看到你在用否决票否决我的答案,自动stackexchange审核器也会。我看到你不熟悉其他基于JVM的语言,或者任何类型的原型。我明白你的意思。那么在这种情况下我该怎么办?使b同步,这样就不会发生中断?如果只从a调用b
,您就没事了。为了安全起见,可以同步类中的任何入口点(public、protected、default)方法。这样,实际上可以保证一次只有一个线程可以使用该对象。另外,请确保不要直接操作公共、受保护或默认变量,因为您可以使用与方法设置完全相同的方法进行处理。有关此主题的详细说明,请参阅SCJP 6学习手册@格雷格:我看到你用否决票否决了我的答案,自动stackexchange Auditer也会。我看到你不熟悉其他基于JVM的语言,或者任何类型的原型。很多年过去了,但我认为ReentrantReadWriteLock应该做你希望做的事。很多年过去了,但我认为ReentrantReadWriteLock应该做你希望做的事情。