-2

com.offbynull.coroutines バージョン 1.1.0 コンシューマは 7500 メッセージしか消費しません。

7500このコードが ではなくメッセージのみを消費する理由を理解してください30000


public class DemoProducerConsumer {

    public static int cnt = 0;
    public static final int MAX = 10000;

    public static class Producer implements Coroutine {

        @Override
        public void run(Continuation ctn) throws Exception {
            String thName = Thread.currentThread().getName();
            System.out.println(thName + ") Producer starting...");
            Consumer consumer = new Consumer();
            for (int i = 0; i < 3; i++) {
                consumer.consume(ctn, "Hello:" + i);
            }
            System.out.println(thName + ") Producer published 3 messages");
        }
    }

    public static class Consumer {    
        public void consume(Continuation ctn, String message) {
            String thName = Thread.currentThread().getName();
            System.out.println(thName + ")" + message);
            cnt++;  // <<< SUSPECT bug here.
            ctn.suspend();  // <<< SUSPECT bug here.
        }
    }

    public static final void main(String... args) throws InterruptedException {

        String thName = Thread.currentThread().getName();
        System.err.println(thName + ") Preparing Producer ");

        new Thread(new Runnable() {
            public void run() {
                cnt = 0;
                Producer producer = new Producer();
                CoroutineRunner runner = new CoroutineRunner(producer);
                for (int i = 0; i < MAX; i++) {
                    runner.execute();
                }
                System.out.println(thName + ") Producer Looped " + MAX + " times.");
            }
        }).start();
        System.err.println(thName + ") Waiting " + (MAX * 3) + " message to be consumed...");
        Thread.sleep(10000);
        System.err.println(thName + ") Message consumed:" + cnt);
        System.err.println(thName + ") Exiting...");
    }    
}

Thread Poolこれを使用して、より高性能な MVC サーバーを実装する予定です。

消費者と生産者の分離は必須です。

4

1 に答える 1

1

コルーチンの作成者はこちら。execute() メソッドの仕組みを誤解しているようです。suspend() を呼び出すたびに、execute() が戻ります。execute() を再度呼び出すと、中断した時点からメソッドの実行が続行されます。

したがって、コルーチンを MAX 回完全に実行する場合は、メイン ループを次のように変更する必要があります。

for (int i = 0; i < MAX; i++) {
    boolean stillExecuting;
    do {
        stillExecuting = runner.execute();
    } while (stillExecuting);
}

それに加えて、別のスレッドからフィールド cnt にアクセスしているため、おそらく cnt を揮発性としてマークする必要があります。

public static volatile int cnt = 0;

上記の変更を加えて実行すると、期待どおりの出力が生成されます。

main) Producer Looped 10000 times.
main) Message consumed:30000
main) Exiting...

また、コルーチンがユースケースに適しているかどうかを評価するために、時間を費やす必要があります。あなたが解決しようとしている問題はわかりませんが、通常の Java スレッド構造の方が適しているようです。

于 2015-06-07T19:37:24.613 に答える