java - Simple one way suspend for thread -
please bare me still new threads...
i have small project have 2 threads listenerthread
, heartbeatthread
both nested classes inside heartbeatserver
.
what have listener thread adds clients registerclients
when sends request (the rest out of scope of question).
i looking simple way suspend heartbeatthread
when there no clients in registerclients
hashmap.
originally thinking easy using if statement @ top of while loop in listenerthread
checks how many clients there , if client count less 0 listenerthread
call heartbeatserver.heartbeatthread.wait()
, heartbeatserver.heartbeatthread.notify()
when client count zero. when java throws illegalmonitorexception
. after doing digging found out exception because did not call wait()
inside of synchronized
block.
since looking go 1 way listenerthread -> heartbeatthread
, never other way how accomplish this? still better off using synchronized
block in each thread. if that's case need clarification synchronizing.
i found example;
boolean ready = false; // thread 1 synchronized(lock) { ready = true; lock.notifyall(); } // thread 2 synchronized(lock) { while(!ready) lock.wait(); }
this example looks solve me issue. since new not sure lock
supposed be.
could example reworked or completed fit needs or there better way solve issue?
i not sure code need show can post requested.
update
i think worked out solution issue. public class heartbeatserver {
final object lock = new object(); volatile boolean suspended = true; //test use volatile int usercount = 0; // thread send heartbeats client. private class heartbeatthread implements runnable { @override public void run() { heartbeatserver heartbeatserver = heartbeatserver.getinstance(); while (true) { synchronized (heartbeatserver.lock) { if(suspended) { try { system.out.println("suspending heartbeat thread!"); heartbeatserver.lock.wait(); } catch (interruptedexception e) { e.printstacktrace(); } } else { system.out.println("resuming heartbeat thread!"); } // end if block } // end synchronized block try { thread.sleep(2000l); } catch (interruptedexception e) { e.printstacktrace(); } } // end while loop } // end run method } // end heartbeatthread // thread listen clients connecting server. private class listenerthread implements runnable { // instance of heartbeatserver should first object can use everywhere in class. heartbeatserver heartbeatserver = heartbeatserver.getinstance(); private void suspendheartbeats() { synchronized (heartbeatserver.lock) { heartbeatserver.suspended = true; } } // end suspendheartbeats private void resumeheartbeats() { synchronized (heartbeatserver.lock) { heartbeatserver.suspended = false; heartbeatserver.lock.notify(); } } // end resumeheartbeats @override public void run() { while(true) { if(heartbeatserver.usercount < 1) { suspendheartbeats(); } else { resumeheartbeats(); } } // end while loop } // end run method } // end listenerthread } // end heartbeatserver
is there else improve threads? of parts in heartbeatthread left on testing. referring more logic used suspend heartbeatthread.
you sound have found core of need, confidence holding back. wait/notify low level primitives in java , common there subtle timing bug creep in when using them. why higher level abstractions readwritelock, semaphore etc exist. there example in java api docs demonstrating how block until condition (such empty or full) reached here, have used reentrantlock , condition signal empty/not empty.
going question lock object, object calling wait/notify against. can more or less object long same object.
there argument says when using synchronized/wait/notify 1 should use private final object , not publicly exposed object. argument if lock object exposed other code call wait/notify/synchronized against , cause side effect become tricky track down. threaded code hard anyway, argument aiming reduce opportunity external interference creeping in. explains example, following convention.
Comments
Post a Comment