我有10名工人名单的代码和以下两种方法:
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 );
}
}
}
我正在尝试更改这两种方法,以便我让分配器具有100个作业的列表,然后以这样的方式分配:十个工作程序中的每一个在时间上最多给予三个作业,直到达到100为止,即工人1需要工作1,2,3工人2需要4,5,6这样当工人10到达时,它会返回工作人员,分配三个工作直到达到第100个工作,然后它停止并警告所有工作已分配。请帮助我被困......
答案 0 :(得分:2)
虽然您的问题提到了具体的执行顺序,但您的意见似乎表明这不是真正的要求。我建议您使用Java 1.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
更改为Callable
并使用Future
方法返回的submit(Callable)
来获取{返回的结果} {1}}。
答案 1 :(得分:1)
我不同意您的工作分配方法,我认为这就是挂断您的代码。
通常,生产者应该创建工作并将其分配给队列。担心生产工作不是生产者的责任。当工人可以使用时,他们会从队列中取出工作。无论是拉1个工作还是3个工作,都只是工作线程中的逻辑问题。
您可能希望为队列创建单例类。它应该处理接收和请求工作。
通过这种方式接近它可以让工人与生产者分离。您可以根据工作负载/瓶颈要求添加更多生产者或工作者。它还可以防止您生成某种信号机制,工作人员向生产者表明他们已准备好开展更多工作。最后,这使您不必担心各种竞争条件,其中只有一个作业可用,或者作业编号与您在demoDequeue中的幻数不一致。
HTH,对不起,这不是一个直接的答案,但应该让你找到解决问题的更好途径。