CSDN博客

img tenwang1977

在多线程环境中调用native方法[原]

发表于2004/7/9 13:36:00  1224人阅读

这几天忙着写一个用于数据同步的Java程序,在这里遇到了一个令人头大的问题。
问题是这样:我的数据同步程序要同时跑四个线程,在其中的一个线程中,要做一个MD5的文件校验工作。这个MD5的校验是要通过调用一个dll来实现,这个dll(名字叫做MD5Operation.dll)是用于对文件内容进行MD5运算的,目的是用于做服务器端和客户端的文件校验。

类MD5Tool的源代码如下:

package com.hode.util;

public class MD5Tool
{
     public static native String hMd5( String szFilePath);  
     static
     {
           System.loadLibrary( "MD5Operation" );
     }
}

我声明了一个静态的本地方法hMD5,这样我在程序中就可以直接用MD5Tool.hMD5(filePathName)来调用了,经过我的简单测试,程序运行正常。
测试代码如下:

package com.hode.util

public class TestMD5
{
     public static void main(String[] args)
     {
          String filePathName = "C://my music//heal the world.mp3";
          String fileMD5Str = MD5Tool.hMD5(filePathName);
          System.out.println("fileMD5Str=" + fileMD5Str);
     }
}

但是当我把它拿到数据同步的程序中运行,当程序运行到MD5Tool.hMD5(filePathName)这条语句的时候,莫名其妙的终止了,而且不会抛出任何异常,这实在让人看不懂。找了半天的原因,也找不出什么问题,因为毕竟调用MD5的代码就那么几行,把它翻来覆去折腾几遍还是那个样子。我真的有点搞不定了,这时Neil拿来一本《 JAVA线程 》,他找到一页关于调用native方法的相关问题,书中说道,在多线程的环境中,调用native方法时,要声明成synchronized static的,否则会出现问题而导致线程终止。嘿嘿!有点意思了,我赶忙将代码改了过来,我的代码变成了:

package com.hode.util;

public class MD5Tool
{
     public synchronized static native String hMd5( String szFilePath);  
     static
     {
           System.loadLibrary( "MD5Operation" );
     }
}

再次运行,结果让人失望,程序仍然会终止!到底问题出在哪里??我有点灰心了... ...

既然《JAVA 线程》中已经说明了,在多线程的环境下调用native方法可能会出问题,那么是不是因为在子线程中加载dll的时候会有问题呢?不试不知道,一试吓一跳,我把dll的加载放到了主线程中,然后在子线程中进行调用,代码简略如下:

package com.hode.sync.thread;

import com.hode.util.MD5Tool;

public class MainThread extends Thread
{
     private MD5Tool myMD5Tool = new MD5Tool();   //在主线程中加载dll
    
     .... .... ....

     public static void main(String[] args)
     {
           .... .... ....

          SubThread1 T1 = new SubThread1();
          SubThread1.run();

            .... .... ....
     }
}

public class SubThread1 extends Thread
{
     public void run()
     {
           .... .... ....

          String filePathName = "C://my music//heal the world.mp3";
          String fileMD5Str = MD5Tool.hMD5(filePathName); //在子线程中调用hMD5方法
          System.out.println("fileMD5Str=" + fileMD5Str);

          .... .... ....
     }
}

运行成功啦!哦,原来是这样,在调用native方法的时候要注意以下几点:
(1) 在多线程的同时运行的时候,最好将native方法声明成synchronized static。
(2) dll的加载要在主线程中进行,但可以在子线程中调用。

0 0

相关博文

我的热门文章

img
取 消
img