From: "H.Yamamoto" Date: 2006-02-12T20:30:07+09:00 Subject: Re: [QUIZ] FasterGenerator (#66) 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()); } } }