开发者

How do I signal a sleeping thread in Java?

I'm writing a UDP client-server pair for a networks class, and I have hit on a problem. This is a rather unorthodox networks assignment, so a little background first:

The goal is to create a server to implement push-based notifications. The key point here is that the server has to contact the client at whatever address it was last seen, as well listen for the client's control packets. So therefore, I have a thread running on the client periodically sending out UDP packets to the server, which logs their origin for when it needs to send out a response. This technique also busts through NAT's, as the send refreshes the address translation.

So then, here is my dilemma: Unless I'm mistaken, the NAT maps its own address and a generated port number onto it's clients address port combination. Therefore, in order to successfully traverse the NAT, I need to move all my packets through one port on the client machine. The updater thread would simply have to listen for a time, push out an update packet, and go back to listening.

Then here is where it get hairy. If the original thread, which wants to p开发者_JS百科erform some action, wants the port, it has to wake the announcer, which is blocking while waiting for the response.

How can I pull this off in Java?

P.S.: If it turns out that the NAT would allow a communication on a different port to go through, then things are awesome.


Note: I am not necessarily telling you this is the right way to solve your larger problem.

But the answer to your top-line question, "How do I signal a sleeping thread in Java" is: Call interrupt() on the thread. You'll need a more elaborate mechanism in place to communicate why it has been interrupted, but that's a start. interrupt() will wake a sleep()ing or wait()ing thread with an InterruptedException, but I don't think that's really what you're asking.

This will not wake up a thread blocked on a read() call, say a socket. It sounds like you are using a DatagramSocket, in which case you have a couple of options:

  • Use a non-blocking implementation. (aka, "Selector-based", or New I/O (nio) in Java lingo) See e.g. DatagramChannel; also maybe this SO question and/or this one
  • Use normal Java I/O, set a socket timeout of suitable length, and wrap your calls to read() in a loop, checking for the appropriate condition.


Look at the following links :

  • Thread signaling
  • What is a condition variable in java
  • Java signal handling


How is the thread 'sleeping'?

Typically, inter-thread cooperation revolves around

wait() and notify() calls.


Selectors are one approach I would consider. Haven't used Java's version yet, so take this with a grain of salt.

You could have one selector watching both the UDP channel and an in-process channel, waking up on activity of either.

There's an introduction to selectors halfway down http://java.sun.com/developer/technicalArticles/releases/nio/ . See also the API docs of AbstractSelector and its interface.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜