土曜日, 5月 03, 2014

マルチスレッド - notifyとwait

問題
There are three threads in a process. The first thread prints 1 1 1 …, the second one prints 2 2 2 …, and the third one prints 3 3 3 … endlessly. How do you schedule these three threads in order to print 1 2 3 1 2 3 …?
(Coding Interviews, Analysis & Solutions より引用)

ヒント
各スレッド間でchain of responsibility的に連係動作させるか,マスタスレッドがnotify/waitを利用してオーケストレーションするか等,解法は色々ある.

解答

ここではヒントの後者の方法を実装してみた.

package org.tanuneko;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by morinoko on 5/3/2014.
 */
public class MyThread implements Runnable {

    private static final int NUM_TH = 3;
    private final int id;
    private final int val;
    private static Object[] objs = new Object[NUM_TH];

    static {
        for( int i = 0;i < objs.length;i++ ) {
            objs[i] = new Object();
        }
    }

    public MyThread( int id,int val ) {
        this.id = id;
        this.val = val;
    }

    public void run() {

        while( true ) {

            synchronized( objs[id] ) {

                try {
                    objs[id].wait();
                } catch ( InterruptedException iE ) {
                    iE.printStackTrace();
                }
            }
            System.out.println( val );

        }
    }

    public static void main( String args[] ) throws InterruptedException {

        ExecutorService s = Executors.newFixedThreadPool( NUM_TH );
        for( int i = 0;i < NUM_TH;i++ ) {
            s.execute( new MyThread( i, i + 1) );
        }

        int invokeTarget = 0;
        while( true ) {
            synchronized( objs[invokeTarget] ) {
                objs[invokeTarget].notify();
            }

            Thread.sleep( 1000 );
            invokeTarget = ++invokeTarget % NUM_TH;
        }

    }

}

0 件のコメント: