0

私は10人の労働者のリストと以下の2つの方法のコードを持っています:

public void demoDeques() {
        int maxSizeOfJobDeque = 3;
        Producer producer = new ProducerImpl( maxSizeOfJobDeque );

        Logger.debug( "WorkFlowEngineImpl : " +
                "Creating Workers and adding them to allocator" );
        List<Worker> workerList = buildWorkerList( producer );
        Logger.debug( "WorkFlowEngineImpl : " +
                "Assigning some jobs to the workers. " +
                    "The workers have not been started yet");

        for ( int i=1; i<4; i++ ) {
            producer.assign( new JobImpl( "job " + i, i ) );
            try {
                Thread.sleep( 4000 );
            } catch( InterruptedException e ) {
                e.printStackTrace();
            }
        }

        Logger.debug( "WorkFlowEngineImpl : " + "Starting the workers" );
        startWorkersAndWait5Seconds( workerList );
        Logger.debug( "WorkFlowEngineImpl : " +
                "Assigning some more jobs to the " +
                    "started workers" );

        for ( int i=4; i<7; i++ ) {
            producer.assign( new JobImpl( "Job " + i, i ) );
            try {
                Thread.sleep( 4000 );
            } catch( InterruptedException e ) {
                e.printStackTrace();
            }
        }

        Logger.debug( "WorkFlowEngineImpl : " + "Assigning More Jobs" );
        for ( int i=7; i<11; i++ ) {
            producer.assign( new JobImpl( "job" + i, i ) );
            try {
                Thread.sleep( 4000 );
            } catch( InterruptedException e ) {
                e.printStackTrace();
            }
        }
    }

プロデューサー:

public synchronized void assign( Job job ) {
    Set<Worker> workerSet = jobMap.keySet();
    LinkedBlockingDeque<Job> jobQueue;
    StringBuffer sb;

    for ( Worker worker : workerSet ) {
        jobQueue = jobMap.get( worker );

        sb = new StringBuffer();
        sb.append( "Assigning job " );
        sb.append( job.getJobNumber() );
        sb.append( " to " );
        sb.append( worker );
        sb.append( "'s jobs Deque" );

        Logger.debug( "Producer : " + sb.toString() );

        if ( ! jobQueue.offerFirst( job ) ) { 
            jobQueue.pollLast();
            jobQueue.offerFirst( job );
        }
    }
}

2 つの方法を変更して、アロケーターに 100 のジョブのリストを持たせ、100 に達するまで一度に最大 3 つのジョブが 10 人のワーカーに割り当てられるように割り当てます。ジョブ 1,2,3 ワーカー 2 は 4,5,6 を取得するため、ワーカー 10 に到達するとワーカー 1 に戻り、100 番目のジョブに到達するまで 3 つのジョブを割り当てて停止し、すべてのジョブが割り当てられたことを警告します。私が立ち往生しているのを助けてください....

4

2 に答える 2

2

あなたの質問は特定の実行順序に言及していますが、あなたのコメントはこれが本当の要件ではないことを示しているようです。独自のスレッドプールを実装する代わりに、Java1.5でExecutors提供されているものを使用することをお勧めします。例えば:

ExecutorService threadPool =
    Executors.newFixedThreadPool(NUMBER_THREADS_TO_RUN_JOBS);
// your producers then just have to submit jobs to the pool
for ( int i=1; i<4; i++ ) {
    threadPool.submit(new JobImpl("Job " + i, i));
}

あなたの例からは、各「ジョブ」でどのような処理を行う必要があるかを正確に知ることはできませんが、上記のコードを機能させるためJobImplに実装する必要があるかどうかはわかりません。Runnableジョブから何らかの値を返す必要がある場合はJobImpl、beに変更し、メソッドによって返されたものCallableを使用して、によって返される結果を取得できます。Futuresubmit(Callable)call()

于 2012-04-24T13:54:55.893 に答える
1

私はあなたの仕事の割り当て方法に同意しません。それがあなたのコードをハングアップさせていると思います。

一般に、プロデューサーは作業を作成し、それをキューに割り当てる必要があります。仕事の分配について心配するのはプロデューサーの責任ではありません。ワーカーが使用可能になると、キューからジョブを取得します。1 つのジョブをプルするか 3 つのジョブをプルするかは、プルするときのワーカー スレッド内のロジックの問題です。

おそらく、キューのシングルトン クラスを作成する必要があります。ジョブの受信と要求を処理する必要があります。

このようにアプローチすると、ワーカーをプロデューサーから切り離すことができます。ワークロード/ボトルネックに応じて、プロデューサーまたはワーカーを追加できます。また、ワーカーがプロデューサーに次の作業の準備ができていることを示す、ある種のシグナル伝達メカニズムを生成することもできなくなります。最後に、これにより、利用可能なジョブが 1 つしかない場合や、ジョブの番号付けが demoDequeue 内のマジック ナンバーと一致しない場合のさまざまな競合状態について心配する必要がなくなります。

HTH、申し訳ありませんが、直接的な回答ではありませんが、問題を解決するためのより良い道を歩むことができます.

于 2012-04-24T13:52:25.083 に答える