Hello. Please add this to quiz's rule.

Generator should suspend current calculation, and
resume it when next() is called. (I uses @queue as
array, but this is just for insurance. normally
@queue should not contain multiple values)

//////////////////////////////////////////

require "test/unit"
require "generator"

class TestGenerator < Test::Unit::TestCase

  class C
    def value=(x)
      @value = x
    end
    def each
      loop do
        yield @value
      end
    end
  end

  def test_realtime
    c = C.new
    g = Generator.new(c)
    3.times do |i|
      c.value = i
      assert_equal(i, g.next())
    end
  end

end

//////////////////////////////////////////

And python supports generator natively,
this behaves like HEAD's Generator class.

def generator():
  global value
  while True:
    yield value

g = generator()
for i in xrange(3):
  value = i
  print g.next()

////////////////////////////////////////////

And this one is Java version.


abstract class CoRoutine
{
    private final Thread _thread;

    private final Object _lock = new Object();

    private java.util.LinkedList _list = new java.util.LinkedList();

    private boolean _terminated = false;

    public CoRoutine()
    {
        final Object first_lock = new Object();

        _thread = new Thread()
        {
            public void run()
            {
                synchronized(_lock)
                {
                    synchronized (first_lock)
                    {
                        first_lock.notify();
                    }

                    try
                    {
                        _lock.wait();
                    }
                    catch (InterruptedException e)
                    {
                        throw new RuntimeException(e); // ???
                    }

                    try
                    {
                        CoRoutine.this.run();
                    }
                    finally
                    {
                        _terminated = true;

                        _lock.notify();
                    }
                }
            }
        };

        _thread.setDaemon(true);

        synchronized(first_lock)
        {
            _thread.start();

            try
            {
                first_lock.wait();
            }
            catch (InterruptedException e)
            {
                throw new RuntimeException(e); // ???
            }
        }
    }

    protected abstract void run();

    protected final void yield(Object value)
    {
        synchronized(_lock)
        {
            _list.add(value);

            _lock.notify();

            try
            {
                _lock.wait();
            }
            catch (InterruptedException e)
            {
                throw new RuntimeException(e); // ???
            }
        }
    }

    private void ready() // must be called in synchronized(_lock)
    {
        if (!_terminated && _list.isEmpty())
        {
            _lock.notify();

            try
            {
                _lock.wait();
            }
            catch (InterruptedException e)
            {
                throw new RuntimeException(e); // ???
            }
        }
    }

    public boolean hasNext()
    {
        synchronized(_lock)
        {
            ready();

            return !_list.isEmpty();
        }
    }

    public Object next()
    {
        synchronized(_lock)
        {
            ready();

            if (_list.isEmpty())
            {
                throw new RuntimeException("EOF");
            }

            return _list.removeFirst();
        }
    }
}

//////////////////////////////////////////////////
// Main

class Test extends CoRoutine
{
    public int value;

    protected void run()
    {
        while (true)
        {
            yield(value);
        }
    }
}

class Main
{
    public static void main(String[] args)
    {
        Test t = new Test();

        for (int i = 0; i < 3; ++i)
        {
            t.value = i;

            System.out.println(t.next());
        }
    }
}