Java并发线程池中不执行多个thead
我有一个项目,其中我有一个客户端,可以调用Web服务器。Web服务器连续打开一个到另一个提供XML文件的服务器的连接。此XML文件被转换为Java对象。要执行这些操作,我使用线程池。 首先,有一个带有while循环的工作线程。在循环中,我调用另一个方法来检索XML数据Java并发线程池中不执行多个thead,java,multithreading,concurrency,threadpool,synchronized,Java,Multithreading,Concurrency,Threadpool,Synchronized,我有一个项目,其中我有一个客户端,可以调用Web服务器。Web服务器连续打开一个到另一个提供XML文件的服务器的连接。此XML文件被转换为Java对象。要执行这些操作,我使用线程池。 首先,有一个带有while循环的工作线程。在循环中,我调用另一个方法来检索XML数据 public static void startXmlRetrieval( String sbeSystem, String params ) throws Exception { Processable xmlEvent
public static void startXmlRetrieval( String sbeSystem, String params ) throws Exception {
Processable xmlEventTask = sTaskWorkQueue.poll();
if ( xmlEventTask == null )
xmlEventTask = new EventXMLTask( sInstance );
else if ( !(xmlEventTask instanceof EventXMLTask) )
xmlEventTask = new EventXMLTask( sInstance );
((EventXMLTask) xmlEventTask).setXmlRetrievalParams( params );
((EventXMLTask) xmlEventTask).setXmlRetrievalAddr( sbeSystem );
sTaskWorkQueue.add( xmlEventTask );
synchronized ( sLockObject ) {
System.out.println( "Initiating thread to retrieve XML feed" );
sThreadPool.execute( ((EventXMLTask) xmlEventTask).getTaskRunnable());
// send the continuous thread from the ServerSessionHandler class to wait for this execution to finish
sLockObject.wait();
}
}
上述方法执行并返回到声明该方法的对象
@Override
public void handleState( Processable task, int state ) throws Exception {
switch ( state ) {
case XML_RETRIEVAL_FAILED:
recycleXMLTask( (EventXMLTask) task );
//throw new Exception( "XML retrieval failed" );
case XML_RETRIEVAL_COMPLETED:
synchronized ( sLockObject ) {
ConvertManager.startXMLConversion( sInstance, sXmlData );
}
break;
case DATABASE_RETRIEVAL_FAILED:
case DATABASE_RETRIEVAL_COMPLETED:
recycleDatabaseTask( (DatabaseTask) task );
break;
case UNX_COMMAND_EXEC_FAILED:
case UNX_COMMAND_EXEC_COMPLETED:
recycleUnxCommandExecTask( (CommandOutputRetrievalTask) task );
break;
case ConvertManager.XML_CONVERSION_COMPLETED:
synchronized ( sLockObject ) {
removeXMLEventRetrieval( (TaskBase) task );
sLockObject.notifyAll();
}
break;
}
}
在cas部分“XML_RETRIEVAL_COMPLETED”中,我想将另一个线程传递到同一线程池,以执行XML数据的转换。
问题是ConvertManager.startXMLConversion方法被执行,但当涉及到提交可调用(FutureTask)的线程池上的submit时,此调用方法不再执行。
对于调试器中的线程组,它表示“WAIT”,并且它当前卡在从FutureTask.waitdone方法调用的Unsafe.park方法中
请帮助我了解线程正在等待什么,因为我使用了synchronized语句,一个线程等待另一个线程,但另一个线程只执行到某个点,并且停止。我还尝试在sLockObject上使用notify和notifyAll,但没有成功
ConvertManager.startXmlConversion方法如下所示:
public static List<XMLEventData> startXMLConversion( AbstractManager mng, Document xmlDocument ) throws Exception {
sInstance.mCallingManager = mng;
List<XMLEventData> retVal;
Processable converterTask = sInstance.sTaskWorkQueue.poll();
try {
if ( converterTask == null )
converterTask = new XMLToXMLEventConverterTask( sInstance );
else if ( !(converterTask instanceof XMLToXMLEventConverterTask) )
converterTask = new XMLToXMLEventConverterTask( sInstance );
else if ( ((XMLToXMLEventConverterTask) converterTask).getTaskCallable() == null ) {
converterTask = new XMLToXMLEventConverterTask( sInstance );
}
sTaskWorkQueue.add( converterTask );
((XMLToXMLEventConverterTask) converterTask).setXmlDocument( xmlDocument );
System.out.println( "Starting new thread to convert XML data" );
retVal = (List<XMLEventData>) sThreadPool.submit( ((XMLToXMLEventConverterTask) converterTask).getTaskRunnable() ).get();
} catch ( Exception e ) {
e.printStackTrace();
throw new Exception( e );
}
return retVal;
}
公共静态列表startXMLConversion(AbstractManager mng,Document xmlDocument)引发异常{
sInstance.mcalingmanager=mng;
列表检索;
可处理转换器任务=sInstance.sTaskWorkQueue.poll();
试一试{
if(converterTask==null)
converterTask=新的XMLToXMLEventConverterTask(sInstance);
else if(!(XMLToXMLEventConverterTask的转换器任务实例))
converterTask=新的XMLToXMLEventConverterTask(sInstance);
else if(((XMLToXMLEventConverterTask)converterTask).getTaskCallable()==null){
converterTask=新的XMLToXMLEventConverterTask(sInstance);
}
sTaskWorkQueue.add(converterTask);
((XMLToXMLEventConverterTask)converterTask).setXmlDocument(xmlDocument);
System.out.println(“启动转换XML数据的新线程”);
retVal=(List)sThreadPool.submit((XMLToXMLEventConverterTask)converterTask.getTaskRunnable()).get();
}捕获(例外e){
e、 printStackTrace();
抛出新异常(e);
}
返回返回;
}
提前谢谢你 现在,根据您的描述(实际上拥有完整的类将非常有帮助!),我假设您的
sLockObject
出现死锁,因为您使用此对象锁定创建了许多同步块。(您可以看到线程处于等待状态)。Notify/NotifyAll只有在线程正在等待时才有效,如果线程中出现死锁,则它不会有任何帮助code@asettouf总共有三个同步块。你说只使用这个synchronized语句一次可能有助于避免死锁?我可以将正在使用的类上传到我的github,这样你就可以浏览一下了。我非常感谢你的帮助。谢谢请上传你的课程。我想说的是,您的代码(正如我所看到的)可能会导致死锁,如果没有其他信息,我不能肯定地说什么。问题是,如果使用synchronize,我认为这是为了避免数据竞争,因此通过删除同步块,您可能会遇到这个问题,这最终不是一个很好的解决方案。(再次查看代码将有助于澄清所有这些假设)您可以删除它们,尽管我建议您使用“清理”版本,以便其他人也能提供帮助…@asettouf是个好主意。我还给你写了一封gmail。我将删除它并上传一个新版本。现在,根据您的描述(实际上拥有完整的类将非常有帮助!),我假设您的sLockObject
出现死锁,因为您使用此对象锁定创建了许多同步块。(您可以看到线程处于等待状态)。Notify/NotifyAll只有在线程正在等待时才有效,如果线程中出现死锁,则它不会有任何帮助code@asettouf总共有三个同步块。你说只使用这个synchronized语句一次可能有助于避免死锁?我可以将正在使用的类上传到我的github,这样你就可以浏览一下了。我非常感谢你的帮助。谢谢请上传你的课程。我想说的是,您的代码(正如我所看到的)可能会导致死锁,如果没有其他信息,我不能肯定地说什么。问题是,如果使用synchronize,我认为这是为了避免数据竞争,因此通过删除同步块,您可能会遇到这个问题,这最终不是一个很好的解决方案。(再次查看代码将有助于澄清所有这些假设)您可以删除它们,尽管我建议您使用“清理”版本,以便其他人也能提供帮助…@asettouf是个好主意。我还给你写了一封gmail。我将删除它并上传一个新版本。