Dus*_* E. 5 java concurrency sync
我正在制作一个程序,其中x个线程池与共享库存交互.在这种情况下,我使用ArrayList作为共享库存.在我的程序中,线程是生物具有的作业的表示.生物属于一方并共享用于执行工作的工件池.只有一个生物我随时与游泳池互动.
出于某种原因,我一直遇到线程通信问题.我已经设置了它,所以如果没有使用游泳池,该生物会将所有物品放入游泳池并开始查看它.如果他们找不到他们需要的所有东西,他们应该将他们拥有的所有工件放入池中,将池设置为不忙,然后发出一个等待池的生物发出信号,表示它已经准备好让它们通过它.
我的问题是,如果一个生物正在通过水池观察而另一个正在等待,并且它无法找到它想要的东西,它会重复该过程而不会通知或让其他生物通过它.
我尝试过的:我最初尝试使用锁,但锁不会发出其他线程的信号.然后我利用synchronized(Party)重写了它.然后我认为这是因为线程在某个地方崩溃,但线程可以一直运行,甚至在作业完成时将其项目转储回池中(假设生物没有将池锁定到空中).
boolean ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
//checks to see if creature already has correct amount of each item.
//If it does it should skip pool interaction until it dumps its used items
//back into the pool.
System.out.println( "Ready: " + ready );
while ( !ready ) {//begin pool interaction
synchronized ( target.poolParty ){
System.out.println( "Ready: " + ready );
System.out.println( this );
while ( target.poolParty.busyPool ) {//busyPool is initialized false
startJob.setEnabled( false );
try {
target.poolParty.wait();
} catch ( InterruptedException e ) {}
}
synchronized ( target.poolParty ) {
target.poolParty.busyPool = true;
target.poolParty.notifyAll();//notify all threads that they need to wait because this one will proceed
}
}
target.releaseArtifacts();// adds all artifacts held by creature to an arraylist in poolParty
//then clears the creatures inventory
target.pickUpArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
if ( ready ) {
synchronized ( target.poolParty ) {
System.out.println( "has required Items" );
target.poolParty.busyPool = false;
target.poolParty.notify();
}
} else {
synchronized ( target.poolParty ) {
System.out.println( "Does not has required Items" );
target.poolParty.busyPool = false;
target.releaseArtifacts();
target.poolParty.notifyAll();
try {
Thread.sleep( 1000 );
} catch ( InterruptedException e ){}
}
}
}//end pool interaction
Run Code Online (Sandbox Code Playgroud)
我在线程中执行这种交互,在一个场景中,一个生物有一个以上的工作,但一次只能做一个工作而且它完美地工作.我根据这种情况量身定制了这些方法,但我仍然遇到问题.
注意:我对并发很新,所以请原谅我,如果我的词汇不是在这个主题上发展的话.
看起来您正睡在一个用于target.poolParty同步的块中。这意味着等待访问该池的其他线程将无法访问它,因为该线程正在阻塞它。移到sleep()该方块之外。
在另一个地方,您synchronized (target.poolParty)在已经使用它进行同步的块中使用。这是不必要的(好吧,整个代码块都是不必要的,我删除了它。只是指出)。和wait()也是notify*()低级同步原语,很少需要。
boolean ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
//checks to see if creature already has correct amount of each item.
//If it does it should skip pool interaction until it dumps its used items
//back into the pool.
System.out.println( "Ready: " + ready );
while ( !ready ) {
// begin pool interaction
synchronized (target.poolParty) {
target.pickUpArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
ready = target.hasReqArtifacts( reqStones, reqPotions, reqWands, reqWeapons );
/* I'd move this here. If we never release out items then the
other party members can't use them while this one still does
not have the needed items. Now they will be available to
other parties while this thread sleeps. */
if (!ready) {
// adds all artifacts held by creature to an arraylist in poolParty
target.releaseArtifacts();
}
}
// These don't access the pool, so they can be outside the synchronized block
if ( ready ) {
System.out.println( "has required Items" );
} else {
System.out.println( "Does not have required Items" );
// Sleep before the next try to get the required items. Lets other
// threads attempt to fetch their needed items
try {
Thread.sleep( 1000 );
} catch ( InterruptedException e ) {
// Added, because silently eating exceptions is a bad idea
e.printStackTrace();
}
}
}//end pool interaction
Run Code Online (Sandbox Code Playgroud)