I have main thread which calls another thread. timeout period of second one is 15 seconds. Current implementaion is main thread check second one for every 2 seconds. What I need to do is wait for only as long as second thread finish, upto a maximum of 15 seconds. I thought of trying wait and notify, but it will require synchronized. I am thinking of using Lock. I havent tried it before. Please help me on this.
Thanks
This idea can be implemented? by using timedwait on a lock object in the first thread. The second thread once done should notify on the lock object. This will wake up the first thread. Also, timedwait will force a max wait of 15 seconds.
Updated the solution, I tried.
public class MyThread {
Object obj = new Object();
boolean isDone = false;
int timeOut = 0;
int runTime = 0;
int id = 0;
public static void main(String[] args) throws Exception {
MyThread mainThread = new MyThread();
mainThread.timeOut = Integer.valueOf(args[0]);
mainThread.runTime = Integer.valueOf(args[1]);
System.out.println("<---- mainThread.timeOut ---------->" + mainThread.timeOut);
System.out.println("<---- mainThread.runTime ---------->" + mainThread.runTime);
ChildThread childThread = new ChildThread(mainThread);
childThread.start();
try {
synchronized (mainThread.obj) {
//Wait the current Thread for 15 seconds
mainThread.obj.wait(mainThread.timeOut * 1000);
}
System.out.println("<---- runTime Over ---------->");
if (mainThread.isDone)
System.out.println("<---- done ---------->");
else
System.out.println("<---- not done ---------->");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void test() {
System.out.println("<--- In business Test method --->");
try {
//Call the bussiness method which may take more time
Thread.sleep(runTime * 1000);
if (runTime <= timeOut)
isDone = true;
} catch (InterruptedException e) {
开发者_JAVA百科 e.printStackTrace();
}
System.out.println("<---- completes business test method -->");
}
}
class ChildThread extends Thread {
MyThread mainThread;
ChildThread(MyThread mainThread) {
this.mainThread = mainThread;
}
public void run() {
System.out.println("ChildThread: the run method");
mainThread.test();
//Finished the work,notify the waiting thread.
synchronized(mainThread.obj) {
mainThread.obj.notify();
}
}
}
Get the waiting thread to block on a Semaphore with acquire()
, and have the signalling thread increment it with release()
.
Detailed explanation
The semaphore is a synchronisation primitive that maintains a count. This count has no intrinsic meaning, but usually indicates how many of some kind of "resource" are "available". The semaphore has two basic operations: increment and decrement. Increment never blocks. Decrement blocks if the semaphore's count is zero, and unblocks when another thread increments the semaphore. If multiple threads are blocked on decrement, only one is unblocked for each increment.
In the present case, you create a semaphore with an initial count ("permits
") of zero that the two threads have access to. The first thread waits by decrementing the semaphore, which blocks the thread until the second thread increments the semaphore.
It sounds like a FutureTask would suit your purposes. See http://download.oracle.com/javase/6/docs/api/java/util/concurrent/FutureTask.html
The basic idea is that you can turn your second thread into a Callable and then wrap it in the FutureTask. You can then call get with a timeout on the FutureTask.
I have updated the question with answer.
Use WaitForSingleObject() function which returns when the specified object is in the signaled state or the time-out interval elapses.
WaitForSingleObject(hThread, 15000);
Where hThread is the handle of the second thread.
精彩评论