以下java代码在主线程中创建2个线程。在创建的2个线程上,调用一个执行I / O功能的C函数。然后从主线程调用另一个C函数(againCallReadFile
),然后调用firstThread
方法。这种先前称为的方法很可能正在睡觉或仍然在做它的工作。现在,我怎样才能确保在它返回或完成工作后调用此synchronised method
?
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
内的代码等到java中的方法firstThread
完成,或者有什么方法可以让我知道在调用synchronized函数之前我必须等待?
答案 0 :(得分: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();
}
在这种情况下,线程会互相等待。