Java8 在并行流中的终端操作中,自定义 SWT 侦听器中的流失败
Java8 Stream fails inside custom SWT listener on terminal operation in parallel stream
Java8 在终端操作时自定义 SWT 侦听器中的流失败。
在本机实现的侦听器中使用时成功。
主要区别在于使用 org.eclipse.swt.widgets.Control.setMenu(Menu menu) 应用一个。我感觉这是一个无效的线程访问问题,与 Java8 如何使用线程池创建并行流线程有关。
捕获异常:
org.eclipse.swt.SWTException: Unspecified error
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.util.concurrent.ForkJoinTask.getThrowableException(Unknown Source)
at java.util.concurrent.ForkJoinTask.reportException(Unknown Source)
at java.util.concurrent.ForkJoinTask.invoke(Unknown Source)
at java.util.stream.FindOps$FindOp.evaluateParallel(Unknown Source)
工作实例:
@Override
public void mouseDown(MouseEvent e) {
if (e.widget instanceof Table) {
tableRightClicked = (Table) e.widget;
rightClickLocation = new Point(e.x, e.y);
if(e.button != 1){//user right clicked table! display tableMenu
if(Constants.debug)System.out.println("RIGHT MOUSE BUTTON CLICKED IN TABLE");
Stream<ToolsetAvailability> resourceAvail = scenarioMap.get("5-Year Mar. 2016 1. Single Source").availabilityData.parallelStream().filter(availability -> availability.resourceID.equals("3004"));
System.out.println("resourceAvail count:"+resourceAvail.count());
失败实例:
public SelectionListener menuSelectionListener = new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent arg0) {
Stream<ToolsetAvailability> resourceAvail = scenarioMap.get("5-Year Mar. 2016 1. Single Source").availabilityData.parallelStream().filter(availability -> availability.resourceID.equals("3004"));
System.out.println("resourceAvail count:"+resourceAvail.count());
}
--- 代码适用于单线程流,因此访问自定义侦听器是否会阻塞额外线程?为什么只在终端操作上?
我认为(暂时)这里有两个问题:有什么原因导致 java 并行流调用 reportException
,这可能是次要的或明显的,然后是一些不好的东西当它试图创建异常时发生,就在 java 平台的本机代码层中。看起来它正在尝试通过反射和失败来实例化本机 SWT 异常 class。
我认为整个 scenarioMap / ToolsetAvailability 东西是您的应用程序域的一部分,与 GUI 分开。如果里面有特定于 SWT 的代码,那可能就是问题所在;本机 GUI 层可能不喜欢在意外线程中实例化 GUI 对象。
否则,我假设您已经检查过使用 availabilityData.stream()
而不是 availabilityData.parallelStream()
的代码是否有效?如果不是,这样做可能会向您显示由于其他问题而未在并行案例中报告的根本错误。
Java8 在终端操作时自定义 SWT 侦听器中的流失败。
在本机实现的侦听器中使用时成功。
主要区别在于使用 org.eclipse.swt.widgets.Control.setMenu(Menu menu) 应用一个。我感觉这是一个无效的线程访问问题,与 Java8 如何使用线程池创建并行流线程有关。
捕获异常:
org.eclipse.swt.SWTException: Unspecified error
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.util.concurrent.ForkJoinTask.getThrowableException(Unknown Source)
at java.util.concurrent.ForkJoinTask.reportException(Unknown Source)
at java.util.concurrent.ForkJoinTask.invoke(Unknown Source)
at java.util.stream.FindOps$FindOp.evaluateParallel(Unknown Source)
工作实例:
@Override
public void mouseDown(MouseEvent e) {
if (e.widget instanceof Table) {
tableRightClicked = (Table) e.widget;
rightClickLocation = new Point(e.x, e.y);
if(e.button != 1){//user right clicked table! display tableMenu
if(Constants.debug)System.out.println("RIGHT MOUSE BUTTON CLICKED IN TABLE");
Stream<ToolsetAvailability> resourceAvail = scenarioMap.get("5-Year Mar. 2016 1. Single Source").availabilityData.parallelStream().filter(availability -> availability.resourceID.equals("3004"));
System.out.println("resourceAvail count:"+resourceAvail.count());
失败实例:
public SelectionListener menuSelectionListener = new SelectionListener() {
@Override
public void widgetSelected(SelectionEvent arg0) {
Stream<ToolsetAvailability> resourceAvail = scenarioMap.get("5-Year Mar. 2016 1. Single Source").availabilityData.parallelStream().filter(availability -> availability.resourceID.equals("3004"));
System.out.println("resourceAvail count:"+resourceAvail.count());
}
--- 代码适用于单线程流,因此访问自定义侦听器是否会阻塞额外线程?为什么只在终端操作上?
我认为(暂时)这里有两个问题:有什么原因导致 java 并行流调用 reportException
,这可能是次要的或明显的,然后是一些不好的东西当它试图创建异常时发生,就在 java 平台的本机代码层中。看起来它正在尝试通过反射和失败来实例化本机 SWT 异常 class。
我认为整个 scenarioMap / ToolsetAvailability 东西是您的应用程序域的一部分,与 GUI 分开。如果里面有特定于 SWT 的代码,那可能就是问题所在;本机 GUI 层可能不喜欢在意外线程中实例化 GUI 对象。
否则,我假设您已经检查过使用 availabilityData.stream()
而不是 availabilityData.parallelStream()
的代码是否有效?如果不是,这样做可能会向您显示由于其他问题而未在并行案例中报告的根本错误。