多线程中的race condition问题

08-09-21 freesoftman
         

在多线程中, java语言有一个synchronized关键字, 作用是防止两个或多个线程在同一时间点对相同的对象调用它的method(它:代表该对象中被synchronized关键字修饰的方法)

下面有这么个runnable对象;

public class A extends Runnable {

public synchronized void b() {

...

}

public synchronized void c() {

...

}

public void d() {

...

}

public void run() {

...

}

...

}

现在A对象objectA中有三个线程调用它, 一个是通过Thread(a)构造的本身的线程threadA,还有两个其他的线程threadB,threadC.如果现在threadB调用了方法b(), 那么现在对象objectA被locked住了。按照race condition, 现在其他所有的线程,比如threadC想访问方法c(),那么将会处于等待状态。

问题:

1,如果threadA访问d(),在threadB调用了方法b()还没有返回前, 是否可以执行?

2,如果threadA访问c(),在threadB调用了方法b()还没有返回前, 是否可以执行?

我的理解: 通过synchronized修饰过的方法, 条件:threadB调用了方法b(),对象objectA被锁住了,锁住的是被synchronized修饰过的方法。

1,其他线程包括自身可以访问该对象非synchronized修饰过的方法,如A中的方法d()。

2,其他线程包括自身不可以在此刻访问该对象synchronized修饰过的所有方法,如A中的方法b(),c()。

总结: 就是对象中的线程锁只是锁住了synchronized修饰的方法, 而没有锁住非synchronized修饰的方法。

各位大虾,不知道我这样理解对么? 我们大家一起讨论一下, 看看那位大虾有更好的理解

         

fox0424
2008-09-21 22:07

好像楼主说的有点问题,就是synchronized是只是针对于方法的,而不是针对于对象的。

使用synchronized必然是因为访问了private关键字修饰的集合类型的数据,而并不会锁定持有该集合的对象。

1,如果threadA访问d(),在threadB调用了方法b()还没有返回前, 是否可以执行?

2,如果threadA访问c(),在threadB调用了方法b()还没有返回前, 是否可以执行?

我认为是可以的,当然你可以写一段测试代码实验以下,检验真理的唯一标准就是实践。

banq
2008-09-22 09:11

>如果threadA访问d(),在threadB调用了方法b()还没有返回前, 是否可以执行?

>2,如果threadA访问c(),在threadB调用了方法b()还没有返回前, 是否可以执行?

这里有可能发生性能最大克敌:死锁, 如果threadA访问d()完要访问b();而threadB访问完b()完后,要访问d(),那么两个线程互相把对象下一步需要访问的资源都locked了,那么只能互相等待。

freesoftman
2008-09-23 13:01

“fox0424 :

好像楼主说的有点问题,就是synchronized是只是针对于方法的,而不是针对于对象的。

使用synchronized必然是因为访问了private关键字修饰的集合类型的数据,而并不会锁定持有该集合的对象。”

我认为synchronized是线程同步的一种机制, 而不是针对方法还是对象的。 每个对象都有一个默认的lock,只要某个线程调用了synchronized修饰的方法或 代码块, 那么这个线程就会获得该对象的锁。 其他的线程访问这个对象的synchronized修饰的方法或 代码块就会被挂起。 与private关键字修饰修饰没有关系吧?


freesoftman
2008-09-23 13:10

banq

>如果threadA访问d()完要访问b();而threadB访问完b()完后,要访问d(),那么两个线程互相把对象下一步需要访问的资源都locked了,那么只能互相等待。

恩, 可能会产生死锁, 但是你这么情况下应该不会产生,一下是运行的一种情况:

1,threadA访问d()完要访问b();因为线程threadB没有释放lock,所以threadA处在等待状态。

2,threadB访问完b()完后, 释放lock.

3,threadA访问b(),获得该对象的lock。

4,threadB访问d(), 因为d没有被同步化,所以可以访问。

以上是我的观点。

2Go 1 2 下一页