2012-05-11 29 views
2

以下java代码沿主线程创建2个线程。在创建的2个线程上调用了一个执行I/O功能的C函数。然后从主线程调用另一个C函数(againCallReadFile),然后调用firstThread方法。这个以前叫做的方法很可能是在睡觉或者仍在做它的工作。现在,如何确保在返回或完成工作后将其称为synchronised method如何在同步方法完成其工作之前使c函数等待?

Java代码:

package Package; 


public class Multithreading { 

private native void readFile(); 
private native void writeFile(); 
private native void againCallReadFile(); 

public static void main(String args[]) { 
    Multithreading.firstThread(); 
    Multithreading.secondThread(); 
    // the above functions sleep for 15 seconds 
    new Multithreading().againCallReadFile(); // WILL GIVE THE FATAL ERROR ! B'COZ THAT METHOD SLEEPS FOR 15 SECONDS AFTER IT IS CALLED. 
} 

public synchronized static void firstThread() { 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      System.out.println("First Thread Started at " + new java.util.Date()); 
      System.out.println(); 
      new Multithreading().readFile(); 
      try { 
       Thread.sleep(15 * 1000); // sleep for 15 seconds 
      } catch(Exception exc) { 
       exc.printStackTrace(); 
      } 
     } 
    }; 
    new Thread(r,"FirstThread").start(); 
} 

public synchronized static void secondThread() { 
    Runnable r = new Runnable() { 
     @Override 
     public void run() { 
      System.out.println("Second Thread Started at " + new java.util.Date()); 
      System.out.println(); 
      new Multithreading().writeFile(); 
      try { 
       Thread.sleep(15 * 1000); // sleep for 15 seconds 
      }catch(Exception exc) { 
       exc.printStackTrace(); 
      } 
     } 
    }; 
    new Thread(r,"Second Thread").start(); 
} 

    static { 
     System.loadLibrary("Multithreading"); 
    } 
} 

C代码:

#include "stdio.h" 
#include "string.h" 
#include "Package_Multithreading.h" 

/* 
* Class:  Package_Multithreading 
* Method: readFile 
* Signature:()V 
*/ 

void Java_Package_Multithreading_readFile 
    (JNIEnv *env, jobject obj) { // function that reads a file 

printf("In the C method that reads file!\n"); 
FILE *f_open = fopen("c_io/file_r.txt","r"); 
fseek(f_open,0,SEEK_END); 
long lSize = ftell(f_open); 
rewind(f_open); 
// allocate memory to contain whole file 
char *buffer = (char*)malloc(sizeof(char)*lSize); 
size_t result = fread(buffer,1,lSize,f_open); // file is now loaded in the memory buffer 
int i = 0; 
for(i=0;i<strlen(buffer);i++) { 
    printf("%c",buffer[i]); 
} 
fclose(f_open); 
} 

/* 
* Class:  Package_Multithreading 
* Method: writeFile 
* Signature:()V 
*/ 

void Java_Package_Multithreading_writeFile 
    (JNIEnv *env, jobject obj) { // function that writes a file 

printf("In the C method that writes to the file !\n"); 
char buffer[] = "This data is a result of JNI !"; 
FILE *f_open = fopen("c_io/file_w.txt","wb"); 
int x = fwrite(buffer,1,sizeof(buffer),f_open); 
fclose(f_open); 
printf("Data has been written to the file !"); 
} 

void Java_Package_Multithreading_againCallReadFile 
    (JNIEnv *env, jobject obj) { // function that calls the already called synchronised method 

    // The following snippet calls the function firstThread of java that could be sleeping. It sleeps for 15 seconds ! 

    jclass cls = (*env)->GetObjectClass(env,obj); 
    jmethodID mid = (*env)->GetMethodID(env,cls,"firstThread","()V"); 
    (*env)->CallVoidMethod(env,obj,mid); // call the synchronized method that sleeps for 5 minutes ! 
} 

我怎样才能让里面的代码Java_Package_Multithreading_againCallReadFile等待到的方法firstThread在java中完成或是否有什么办法可以知道,我必须等待,然后调用同步功能?

+2

是的,我们不会阅读所有这些。 – orlp

+1

我可以问你为什么用C写一个文件?大部分编写文件的工作都是由操作系统完成的...... – Renato

+0

@Renato正在测试一些东西......没有什么重要的 –

回答

0

我更喜欢在java端实现同步,而不是在C端。您可以使用锁定进行同步:

private static final Lock lock = new ReentalLock(); 

    public static void firstThread() { 
     final CountDownLatch waitToFinishLatch = new CountDownLatch(1); 
     Runnable r = new Runnable() { 
      @Override 
      public void run() {    
       try { 
        // Will wait until other thread call unloak or if no lock was called: 
        lock.lock(); 
        System.out.println("First Thread Started at " + new java.util.Date()); 
        System.out.println(); 
        new Multithreading().readFile(); 
        try { 
         Thread.sleep(15 * 1000); // sleep for 15 seconds 
        } catch(Exception exc) { 
         exc.printStackTrace(); 
        } 
       } finally { 
        lock.unlock(); 
        waitToFinishLatch.countDown(); 
       } 
      } 
     }; 
     new Thread(r,"FirstThread").start(); 
     try { 
      // Here we are waiting for thread to be finish 
      waitToFinishLatch.await(); 
     } catch(InterruptedException e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public synchronized static void secondThread() { 
     final CountDownLatch waitToFinishLatch = new CountDownLatch(1); 
     Runnable r = new Runnable() { 
      @Override 
      public void run() { 
       try { 
        // Will wait until other thread call unloak or if no lock was called: 
        lock.lock(); 
        System.out.println("Second Thread Started at " + new java.util.Date()); 
        System.out.println(); 
        new Multithreading().writeFile(); 
        try { 
         Thread.sleep(15 * 1000); // sleep for 15 seconds 
        }catch(Exception exc) { 
         exc.printStackTrace(); 
       } finally { 
        lock.unlock(); 
        waitToFinishLatch.countDown(); 
       } 
      } 
     } 
     try { 
      // Here we are waiting for thread to be finish 
      waitToFinishLatch.await(); 
     } catch(InterruptedException e) { 
      throw new RuntimeException(e); 
     } 
    }; 
    new Thread(r,"Second Thread").start(); 
} 

在这种情况下,线程将互相等待。

+2

在这种情况下,这将如何提供帮助! –

+0

@ program-o-steve:添加CountDown闩锁等待线程完成。这会有帮助吗? – alexey28

相关问题