Topic: 关于多线程访问静态方法的问题

  Print this page

1.关于多线程访问静态方法的问题 Copy to clipboard
Posted by: hganbo
Posted on: 2004-12-15 17:21

小弟最近在做一个项目遇到一点线程同步的问题,还没有找出具体的问题。
怀疑问题出在多线程访问静态方法上,但没有找到有相关资料讲这方面的问题,所以只好请教一下各位java高手了。

我的原来程序是这样设计的,对于一些常用的方法,都用静态方法来实现,在多线程程序中直接调用,静态方法由于没有使用静态变量,所以没有进行线程同步。

类似以下程序:

class ThreadI {
public static void main(String[] arg) {

TestI p = new TestI("thread 1");
new TestI("thread 2").start();
new TestI("thread 3").start();
new TestI("thread 4").start();
new TestI("thread 5").start();
new TestI("thread 6").start();
new TestI("thread 7").start();
new TestI("thread 8").start();
new TestI("thread 9").start();
new TestI("thread 10").start();
new TestI("thread 11").start();
new TestI("thread 12").start();
new TestI("thread 13").start();
new TestI("thread 14").start();
new TestI("thread 15").start();
new TestI("thread 16").start();
new TestI("thread 17").start();
new TestI("thread 18").start();
new TestI("thread 19").start();
new TestI("thread 20").start();
p.start();
}
}

class TestI extends Thread {
String s ;
TestI(String sTemp){
this.s = sTemp;
}
public void run() {
try{

Thread.currentThread().sleep( 1000*5);
}catch(Exception ex){}

for(int i=0;i<100;i++){
System.out.println(T.t( this.s + " "+ i));
}
}
}

class T{
public static String t(String sTemp){
String aa = sTemp;
return aa;
}
}

从上面的例子程序打出的结果,我看不出有线程访问冲突的地方。

我的疑问是:对于T.t这种静态方法,在不同线程调用时,jvm究竟是怎么进行处理的?
我自己的理解是对于这样的静态方法是先实例化成各线程堆栈内的具体方法,然后再进行运算,由于都是局部变量,没有使用静态变量,各线程之间是不存在资源冲突的。但没有找到资料来证实这样的理解,所以比较烦恼。还请各位帮忙解决一下。

2.Re:关于多线程访问静态方法的问题 [Re: hganbo] Copy to clipboard
Posted by: tool
Posted on: 2004-12-31 07:47

method的参数和局部变量都是放在堆栈里的,而每个线程都有相互独立的堆栈。所以是没有资源冲突。你的理解基本上正确。

另外要指出的是,代码本身是和其他资源是不同的,不存在实例化的过程。

3.Re:关于多线程访问静态方法的问题 [Re: hganbo] Copy to clipboard
Posted by: bwpc
Posted on: 2004-12-31 11:01

静态方法一个jvm里面就那么一份, 任何时间只能有一个线程访问该方法,大家要排队等候的,呵呵

4.Re:关于多线程访问静态方法的问题 [Re: hganbo] Copy to clipboard
Posted by: colo007
Posted on: 2005-01-10 18:52

好像是这样的。

5.Re:关于多线程访问静态方法的问题 [Re: hganbo] Copy to clipboard
Posted by: bloodwolf
Posted on: 2005-01-13 15:58

Sad靠,什么叫“静态方法一个jvm里面就那么一份”啊!
只有变量或数据才能这么说,而函数方法只是一段计算机指令而已,多线程运行的代码在内存中就一块,只是堆栈和寄存器中的内容(数据)不一样而已。
同步是为了数据互斥访问,并非是代码。
如果定义一个类A中有个需要同步的方法synchronized syn();生成两个A的实例a1和a2,这两个实例的syn()方法是同步不起来的。假如sysn()访问一个static变量,同步是不起作用的。
看来楼上对线程、方法、变量的理解不太透哦。Big Smile

6.Re:关于多线程访问静态方法的问题 [Re: hganbo] Copy to clipboard
Posted by: bwpc
Posted on: 2005-01-13 17:10

我是比较晕, 受教了
那么我想问一下,
一个class的多个实例的在内存中代码块是同一块吗?是不是代码块都是一个,运行的时候传入不同的实例的refrence,参数,然后根据reference到相应堆内操作数据?
另外java的静态方法类似非oop的全局方法, 它是没有特定实例reference的, 运行的时候除了不用传reference之外,和动态方法应该一样吧.

7.Re:关于多线程访问静态方法的问题 [Re: hganbo] Copy to clipboard
Posted by: hganbo
Posted on: 2005-01-17 14:18

项目总结:
终于把内存泄漏问题解决了,不是多线程访问静态函数的问题,事实证明只要在静态函数中没有处理多线程共享数据,就不存在着多线程访问同一个静态方法会出现资源冲突的问题,如果在静态方法中有访问多线程共享数据,就要小心多线程同步问题。

同时,在使用线程池进行开发时,要特别注意线程实例的资源释放问题,不要想当然的认为没有创建变量名来引用所创建的线程实例,线程在运行完就会自动释放资源,事实证明并没有释放。如果没有显示创建变量名引用线程实例,系统会自动创建一个隐藏变量来应用这个实例,会造成线程池运行完线程后依然没有释放资源的问题。

下面是我进行内存泄漏分析后的结果。

项目中使用了EDU.oswego.cs.dl.util.concurrent的线程池进行开发,使用线程池运行线程 ProcessThread 。
public class ProcessThread implements Runnable{ 略}

如果就这样使用线程池运行线程会造成严重的内存泄漏问题:
ThreadPool.getInstance().execute( new ProcessThread(messages[i]) );

代码更改后(如下所示),暂时就没有发现内存泄漏了
ProcessThread thread = new ProcessThread(messages[i]);
ThreadPool.getInstance().execute( thread );
thread = null;


   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923