我正在运行一个多线程 Java 应用程序,它获取对实例进行分类的请求。为了能够同时运行多个线程,我的应用程序在线程之间共享一个Classifier
对象和一个Instances
对象。Instances 对象仅包含属性的相关数据,并且没有任何与之关联的实例。
当我的应用程序收到分类请求时,我Instance
使用请求的属性数据创建一个对象,并使用 将预生成的Instances
对象设置为数据集Instance.setDataset()
,例如:
myNewInstance.setDataset(sharedInstances);
然后myNewInstance
被发送到共享Classifier
。
在大多数情况下,它似乎运作良好。但是有时当发生 2 个并发请求时,会从Classifier.distributionForInstance()
. 不幸的是,错误消息不清楚,但是我看到了 2 个不同的异常:
Caused by: java.lang.RuntimeException: Queue is empty
at weka.core.Queue.pop(Queue.java:194)
at weka.filters.Filter.output(Filter.java:563)
at weka.filters.unsupervised.attribute.PrincipalComponents.convertInstance(PrincipalComponents.java:626)
at weka.filters.unsupervised.attribute.PrincipalComponents.input(PrincipalComponents.java:812)
at weka.classifiers.meta.RotationForest.convertInstance(RotationForest.java:1114)
at weka.classifiers.meta.RotationForest.distributionForInstance(RotationForest.java:1147)
Caused by: java.lang.NullPointerException
at weka.filters.unsupervised.attribute.Standardize.convertInstance(Standardize.java:238)
at weka.filters.unsupervised.attribute.Standardize.input(Standardize.java:142)
at weka.filters.unsupervised.attribute.PrincipalComponents.convertInstance(PrincipalComponents.java:635)
at weka.filters.unsupervised.attribute.PrincipalComponents.input(PrincipalComponents.java:812)
at weka.classifiers.meta.RotationForest.convertInstance(RotationForest.java:1114)
at weka.classifiers.meta.RotationForest.distributionForInstance(RotationForest.java:1147)
如您所见,当最新发生时,它带有一个空消息字符串。
据我了解,我不能使对象不可变,并且我宁愿不将此部分包装在关键部分中,以便充分利用并发性。我尝试使用构造函数为每个分类请求创建一个不同的“实例”对象Instances(Instances dataset)
,但是,它没有产生不同的结果。使用不同Classifier
的选项不是一种选择,因为构建对象需要花费太多时间并且它需要快速响应(最多 10 到 20 毫秒),据我了解,问题并不依赖于此。
我假设问题来自使用相同的 Instances 对象。根据Instances的文档,构造函数只复制对标头信息的引用,这解释了为什么不能通过创建另一个对象来解决问题。是否有一个选项可以根据先前的对象创建完全不同的 Instances 对象,而无需实时查看所有属性?
任何其他以性能为导向的解决方案也将受到高度赞赏。
谢谢!