- 主要编辑:此处包含所有代码 -
package main;
import tree.BinaryTreeAdder;
import tree.BinaryTreeAdderImpl;
import tree.Node;
import tree.NodeImpl;
public class MainClass {
private static Node treeBuilder() {
NodeImpl n0 = new NodeImpl(0);
NodeImpl n1 = new NodeImpl(1);
NodeImpl n2 = new NodeImpl(2);
NodeImpl n3 = new NodeImpl(3);
NodeImpl n4 = new NodeImpl(4);
NodeImpl n5 = new NodeImpl(5);
NodeImpl n6 = new NodeImpl(6);
NodeImpl n7 = new NodeImpl(7);
NodeImpl n8 = new NodeImpl(8);
NodeImpl n9 = new NodeImpl(9);
NodeImpl n10 = new NodeImpl(10);
n0.setSx(n1);
n0.setDx(n2);
n1.setSx(n3);
n1.setDx(n4);
n2.setSx(n5);
n2.setDx(n6);
n3.setSx(n7);
n3.setDx(n8);
n4.setSx(n9);
n4.setDx(n10);
return n0;
}
public static void main(String[] args) {
Node n0 = treeBuilder();
BinaryTreeAdder adder = new BinaryTreeAdderImpl();
int result = adder.computeOnerousSum(n0);
System.out.println(result);
}
}
package processor;
public class FakeProcessor implements OnerousProcessor {
public final static int MIN_COUNT = 1000;
private int max;
private java.util.Random random;
public FakeProcessor(int max) {
this.max = max;
this.random = new java.util.Random();
}
public int onerousFunction(int value) {
int r = this.random.nextInt(this.max);
int n = Math.max(MIN_COUNT, r); // non meno di MIN_COUNT
// useless but onerous
for(int counter=0; counter<n; counter++) {
r = this.random.nextInt(this.max); // maschera casuale
r = r ^ this.random.nextInt(this.max); // inverti i bit
r = r ^ this.random.nextInt(this.max); // due volte
}
return value; // n.b. value risulta invariato
}
}
package processor;
public interface OnerousProcessor {
public int onerousFunction(int value);
}
package thread;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.Callable;
import processor.OnerousProcessor;
import tree.Node;
public class ComputeTask implements Callable<Integer> {
private OnerousProcessor processor;
private BlockingDeque<Node> buffer;
public ComputeTask(BlockingDeque<Node> buffer, OnerousProcessor processor) {
this.buffer = buffer;
this.processor = processor;
}
@Override
public Integer call() throws Exception {
Node currentNode = this.buffer.pop();
Integer value = new Integer(this.processor.onerousFunction(currentNode.getValue()));
if(currentNode.getSx() != null) {
this.buffer.add(currentNode.getSx());
}
if(currentNode.getDx() != null) {
this.buffer.add(currentNode.getDx());
}
return value;
}
}
package tree;
public interface BinaryTreeAdder {
public int computeOnerousSum(Node root);
}
package tree;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import processor.FakeProcessor;
import processor.OnerousProcessor;
import thread.ComputeTask;
public class BinaryTreeAdderImpl implements BinaryTreeAdder {
private BlockingDeque<Node> buffer;
private ExecutorService executor;
public BinaryTreeAdderImpl(/*Node root*/) {
this.buffer = new LinkedBlockingDeque<Node>();
//buffer.add(root);
this.executor = Executors.newFixedThreadPool(8);
}
@Override
public int computeOnerousSum(Node root) {
OnerousProcessor processor = new FakeProcessor(1000);
this.buffer.addLast(root);
List<Future<Integer>> futures = new ArrayList<Future<Integer>>();
while(buffer.size() != 0) {
Callable<Integer> computeThis = new ComputeTask(this.buffer, processor);
futures.add(this.executor.submit(computeThis));
}
int result = 0;
for(Future<Integer> f : futures) {
try {
result += f.get().intValue();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
return result;
}
}
package tree;
public interface Node {
Node getSx(); //null se non esiste figlio sinistro
Node getDx(); //null se non esiste figlio destro
int getValue(); //restituisce un intero associato al nodo
}
package tree;
public class NodeImpl implements Node {
private int value;
private Node leftChild;
private Node rightChild;
public NodeImpl(int value) {
this.value = value;
this.leftChild = null;
this.rightChild = null;
}
@Override
public Node getSx() {
return this.leftChild;
}
@Override
public Node getDx() {
return this.rightChild;
}
@Override
public int getValue() {
return this.value;
}
public void setSx(Node leftChild) {
this.leftChild = leftChild;
}
public void setDx(Node rightChild) {
this.rightChild = rightChild;
}
}
---代码结束---
Hello StackOverflow世界。我需要你的帮助来解决(可能很简单,但仍然不清楚)问题!
我正在构建一个简单的,仅客户端的Java应用程序,以便使用java.util.concurrent和threads进行一些练习。在这个项目中,我必须扫描一棵树,对节点中包含的int值进行一些繁重的计算,并总结得到的值,显示结果。我正在使用轻量级可执行框架。
以下方法来自ComputeTask类,稍后将在引发异常的方法中使用。我不知道它是否相关,但它是:
public Integer call() throws Exception {
Node currentNode = this.buffer.pop();
Integer value = new Integer(this.processor.onerousFunction(currentNode.getValue()));
if(currentNode.getSx() != null) {
this.buffer.add(currentNode.getSx());
}
if(currentNode.getDx() != null) {
this.buffer.add(currentNode.getDx());
}
return value;
}
以下是引发异常的方法:
public int computeOnerousSum(Node root) {
OnerousProcessor processor = new FakeProcessor(1000);
this.buffer.addLast(root);
List<Future<Integer>> futures = new ArrayList<Future<Integer>>();
while(buffer.size() != 0) {
Callable<Integer> computeThis = new ComputeTask(this.buffer, processor);
futures.add(this.executor.submit(computeThis));
}
int result = 0;
for(Future<Integer> f : futures) {
try {
/*exception is raised here*/ result += f.get().intValue();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
return result;
}
其余代码非常简单。
我试图调试,并且发生了一件奇怪的事情:如果我在没有插入前一个方法的调用的情况下进行调试,我会得到堆栈跟踪并且结果为0。 如果我进入computeOnerousSum代替,我可以看到每次都执行catch方法,奇怪的是,结果被正确地求和,直到它达到正确的值55,最后正确打印(在main中)。 / p>
你知道为什么我在调试时能看到正确的行为,更重要的是,为什么该方法仍然会引发NoSuchElementException(这是一个ExecutionException)?
提前谢谢大家, 如果你发现我的解释不清楚或不完整,请问我。
正如所建议的,这是堆栈跟踪!
java.util.concurrent.ExecutionException: java.util.NoSuchElementException
at java.util.concurrent.FutureTask.report(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at tree.BinaryTreeAdderImpl.computeOnerousSum(BinaryTreeAdderImpl.java:31)
at main.MainClass.main(MainClass.java:38)
Caused by: java.util.NoSuchElementException
at java.util.concurrent.LinkedBlockingDeque.removeFirst(Unknown Source)
at java.util.concurrent.LinkedBlockingDeque.pop(Unknown Source)
at thread.ComputeTask.call(ComputeTask.java:19)
at thread.ComputeTask.call(ComputeTask.java:1)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.util.concurrent.ExecutionException: java.util.NoSuchElementException
at java.util.concurrent.FutureTask.report(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at tree.BinaryTreeAdderImpl.computeOnerousSum(BinaryTreeAdderImpl.java:31)
at main.MainClass.main(MainClass.java:38)
Caused by: java.util.NoSuchElementException
at java.util.concurrent.LinkedBlockingDeque.removeFirst(Unknown Source)
at java.util.concurrent.LinkedBlockingDeque.pop(Unknown Source)
at thread.ComputeTask.call(ComputeTask.java:19)
at thread.ComputeTask.call(ComputeTask.java:1)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.util.concurrent.ExecutionException: java.util.NoSuchElementException
at java.util.concurrent.FutureTask.report(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at tree.BinaryTreeAdderImpl.computeOnerousSum(BinaryTreeAdderImpl.java:31)
at main.MainClass.main(MainClass.java:38)
Caused by: java.util.NoSuchElementException
at java.util.concurrent.LinkedBlockingDeque.removeFirst(Unknown Source)
at java.util.concurrent.LinkedBlockingDeque.pop(Unknown Source)
at thread.ComputeTask.call(ComputeTask.java:19)
at thread.ComputeTask.call(ComputeTask.java:1)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
java.util.concurrent.ExecutionException: java.util.NoSuchElementException
at java.util.concurrent.FutureTask.report(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at tree.BinaryTreeAdderImpl.computeOnerousSum(BinaryTreeAdderImpl.java:31)
at main.MainClass.main(MainClass.java:38)
Caused by: java.util.NoSuchElementException
at java.util.concurrent.LinkedBlockingDeque.removeFirst(Unknown Source)
at java.util.concurrent.LinkedBlockingDeque.pop(Unknown Source)
at thread.ComputeTask.call(ComputeTask.java:19)
at thread.ComputeTask.call(ComputeTask.java:1)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
0