Re: "event"-like thread synchronization object?

Discussion in 'Java' started by Mark Space, Jul 15, 2008.

  1. Mark Space

    Mark Space Guest

    Peter Duniho wrote:

    > In some APIs, there's an object that maintains a simple "signaled"
    > state, and which a thread can wait on. For example, in Windows, there's
    > an event handle, which can either reset automatically when a thread is
    > released based on it, or optionally can remain in whatever state until
    > it's explicitly changed by the code.


    I also don't understand the Windows event handle, but what you're
    describing sounds vaguely like Java's Lock interface. Use ReentrantLock
    to implement Lock.

    You can check the state of a Lock as often as you like with tryLock().
    This will block if the lock is locked, and continue otherwise, so
    there's your signaled sate. You can lock() and unlock() the lock as
    often as you like. When a lock is locked, tryLock() will block until
    the lock becomes unlocked, so any number of threads can wait there.

    I don't know what you mean by "reset automatically when a thread is
    released" but the Java docs recommend you call lock() like this:

    Lock lock = new ReentrantLock();

    //...

    lock.lock();
    try {
    //... stuff
    }
    finally {
    lock.unlock();
    }

    which does appear to me to release the lock, regardless of what happens
    inside the try{} block.
    Mark Space, Jul 15, 2008
    #1
    1. Advertising

  2. "Peter Duniho" <> wrote in message
    news:eek:...
    > On Tue, 15 Jul 2008 13:33:50 -0700, Mark Space <>
    > wrote:
    >
    >> [...]
    >> I don't know what you mean by "reset automatically when a thread is
    >> released"

    >
    > Windows has a function, WaitForSingleObject(). There are a number of
    > objects in the OS that have the idea of a "signaled" state, with the event
    > handle being one of the simplest. It does nothing _but_ be signaled or
    > not signaled. So you create an event handle, and then pass that to
    > WaitForSingleObject(). As long as the handle remains unsignaled, the
    > thread waits.
    >
    > Then some other thread "sets" the event (with the SetEvent() Windows
    > function). Once the event handle has been set, the thread that called the
    > wait function can proceed. An event handle can be "manual reset" or "auto
    > reset". An "auto reset" handle will release exactly one thread no matter
    > how many are waiting, and automatically set the event to the unsignaled
    > state when that one thread is released (if no threads are waiting at the
    > moment, the event remains set until some thread does try to wait on it).
    >
    > A "manual reset" event just keeps whatever state was set, signaled or
    > unsignaled. If it comes signaled, then any number of threads that are
    > waiting on it can then proceed, until some thread sets the state back to
    > unsignaled (you could write bad code that causes a race condition where
    > one thread might reset the event before all waiting threads got to
    > proceed, but of course I wouldn't do that :) ).
    >
    >> but the Java docs recommend you call lock() like this:
    >>
    >> Lock lock = new ReentrantLock();
    >>
    >> //...
    >>
    >> lock.lock();
    >> try {
    >> //... stuff
    >> }
    >> finally {
    >> lock.unlock();
    >> }
    >>
    >> which does appear to me to release the lock, regardless of what happens
    >> inside the try{} block.

    >
    > I agree that could be used to simulate the event handle, but it's not
    > really the same thing. The basic semantics are different, which at the
    > very least could cause code maintenance issues, and of course the Lock
    > doesn't have the "auto reset" behavior than an event handle can have.


    I don't mean to put too fine a point on it, but if you are going to program
    in Java, the most effective way to do it is to use Java idioms. I was
    programming in Win32 for about five years, and I was quite familiar with
    Win32 synchronization objects when my career veered into Java. At that time
    (Java 1.2, ca. 1998), the only synchronization that was available in Java
    was synchronized, wait() and notify(). It took some getting used to, but I
    came to appreciate that it was really quite elegant. I only had one
    application where I was forced to roll my own mutex object in all that time.
    Since the java.util.concurrent packages came out in Java 1.5, I haven't felt
    a burning need to use them all that much (I actually think they encourage
    over-design in some cases).

    Once you get used to "thinking in Java", I think you will find that the
    basic synchronization will take you very far. If you are porting from C++ to
    Java, and looking for a one-for-one replacement for some Win32 object, I
    would urge you to reconsider. I think you will find that your Java project
    will be much more successful if you port the design, not the code.
    Chronic Philharmonic, Jul 16, 2008
    #2
    1. Advertising

  3. Mark Space

    Mark Space Guest

    Peter Duniho wrote:

    > I agree that could be used to simulate the event handle, but it's not
    > really the same thing. The basic semantics are different, which at the


    The basic semantics are indeed different. In fact, I misread the docs
    and tryLock() will acquire the lock, meaning any other process will
    block until that process unlocks the lock. Oh well.

    Here's my attempt at an object that will let multiple threads pass until
    it's reset. Unlike the previous example, it uses volatile variables,
    which I think are more efficient than synchronizing.


    class EventHandle {
    volatile boolean state;
    public EventHandle( boolean initialState ) {
    state = initialState;
    }
    public void set() {
    state = true;
    this.notifyAll();
    }
    public void reset() {
    state = false;
    }
    public void waitFor() {
    while( !state ) {
    try {
    this.wait();
    } catch (InterruptedException ex)
    {
    // ignore
    }
    }
    }

    }

    One thing I don't like is that it catches interrupts and ignores them.
    This removes the ability of a thread to set it's own interrupt policy.
    A better implementation should probably pass the exception to the
    caller, but you said you didn't want that. This class synchronizes on
    itself, but I haven't documented that. A real production version should
    call that out carefully in the docs.

    Also, I haven't thought about inheritance, but I left the class
    non-final. Caveat emptor.

    Lastly, I do agree that using Java objects is better than tying to
    duplicate some other operating system's thread IPC semantics. Also, I
    still can't envision exactly what Windows does. English is an informal
    language and not well suited to specifications. Do you think you could
    code this object up? If I could see a working version, I might be able
    to suggest one or two Java objects that do the same thing. That's
    really the only suggestion I have right now.
    Mark Space, Jul 16, 2008
    #3
  4. Mark Space

    thufir Guest

    On Wed, 16 Jul 2008 00:32:47 -0700, Peter Duniho wrote:

    > Java does provide this functionality (as we have discussed in this
    > thread), so saying that's not idiomatic for Java is sort of silly.




    Ah, a thread about threads.



    Sorry, back to your regularly scheduled programming...



    -Thufir
    thufir, Jul 16, 2008
    #4
  5. Mark Space

    Mark Space Guest

    Peter Duniho wrote:

    >
    > I would think a real production version would just use an
    > internally-allocated object for synchronization. IMHO, that's a safer,
    > better-encapsulated approach.


    Not necessarily. The synchronized versions of Collection make an
    explicit guarantee of which public object they synchronize on. It can
    be very handy, since it allows you to modify their behavior, should it
    be necessary. I'm thinking expressly of an sub-class of a Collection or
    EventHandle here, but it applies to composition as well.



    > I don't really understand the question. Both yours and Eric's example
    > do basically the behavior I described; I don't know what else I could
    > "code up" that would explain it better.


    Well, I guess we're done here. What I have posted upthread is so
    trivial that I didn't understand what the heck the fuss was about. I
    assumed there must be more to it. I suppose there's no similar object
    in the Java API because it is simple. By contrast, the full public API
    for Lock and ReentrantLock is pretty large. I would not want to have to
    implement something that complex myself.

    Sorry about that, I didn't mean to hassle you or anything. I just
    didn't understand what was being asked.
    Mark Space, Jul 16, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Vincent Lascaux

    Thread synchronization problem

    Vincent Lascaux, Aug 31, 2004, in forum: Java
    Replies:
    9
    Views:
    387
    John C. Bollinger
    Sep 2, 2004
  2. Razvan

    Thread synchronization

    Razvan, Aug 31, 2004, in forum: Java
    Replies:
    89
    Views:
    1,687
    Lee Fesperman
    Sep 26, 2004
  3. Adam Warner
    Replies:
    13
    Views:
    793
    Patricia Shanahan
    Mar 28, 2006
  4. Patrick Kowalzick
    Replies:
    5
    Views:
    469
    Patrick Kowalzick
    Mar 14, 2006
  5. Arne Vajhøj
    Replies:
    2
    Views:
    372
    John B. Matthews
    Jul 17, 2008
Loading...

Share This Page