Java 8 在已经多线程的环境中使用Java流API
我的应用程序有自己的线程池(myThreadPool),我正在分配一个线程(Producer)通过java流API读取文件。但在运行时,流丢失在某个地方,永远不会到达print方法。但是,当我在单线程环境中运行流时,它可以工作。发生这种情况是因为java stream Api在其下面使用了自己的线程池,还是这在概念上是错误的Java 8 在已经多线程的环境中使用Java流API,java-8,java-stream,Java 8,Java Stream,我的应用程序有自己的线程池(myThreadPool),我正在分配一个线程(Producer)通过java流API读取文件。但在运行时,流丢失在某个地方,永远不会到达print方法。但是,当我在单线程环境中运行流时,它可以工作。发生这种情况是因为java stream Api在其下面使用了自己的线程池,还是这在概念上是错误的 public class Processor { public void process() { ExecutorService myThreadPool =
public class Processor {
public void process() {
ExecutorService myThreadPool = Executors.newFixedThreadPool(3);
myThreadPool.execute(new Producer());
}
private class Producer implements Runnable{
@Override
public void run() {
try (Stream<String> lines = Files.lines(Paths.get("Path"))) {
System.out.println(lines.count());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
公共类处理器{
公共程序(){
ExecutorService myThreadPool=Executors.newFixedThreadPool(3);
myThreadPool.execute(新生产者());
}
私有类生产者实现Runnable{
@凌驾
公开募捐{
try(streamlines=Files.lines(Path.get(“Path”)){
System.out.println(lines.count());
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
}
我不知道你发生了什么事。但我可以给你一个建议(也许你的节目退出了,制片人没有终止)。复制此代码,看看您的代码有什么错误
public class Processor {
public void process() {
ExecutorService myThreadPool = Executors.newFixedThreadPool(3);
try {
myThreadPool.execute(new Producer());
Thread.currentThread().join();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private class Producer implements Runnable {
@Override
public void run() {
try (Stream<String> lines = Files.lines(Paths.get("Path"))) {
System.out.println(lines.count());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
公共类处理器{
公共程序(){
ExecutorService myThreadPool=Executors.newFixedThreadPool(3);
试一试{
myThreadPool.execute(新生产者());
Thread.currentThread().join();
}捕获(例外情况除外){
例如printStackTrace();
}
}
私有类生产者实现Runnable{
@凌驾
公开募捐{
try(streamlines=Files.lines(Path.get(“Path”)){
System.out.println(lines.count());
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
}
或
public class Processor {
public void process() {
ExecutorService myThreadPool = Executors.newFixedThreadPool(3);
try {
myThreadPool.submit(() -> {
new Producer().run();
return null;
}).get();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private class Producer implements Runnable {
@Override
public void run() {
try (Stream<String> lines = Files.lines(Paths.get("Path"))) {
System.out.println(lines.count());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
公共类处理器{
公共程序(){
ExecutorService myThreadPool=Executors.newFixedThreadPool(3);
试一试{
myThreadPool.submit(()->{
新生产者().run();
返回null;
}).get();
}捕获(例外情况除外){
例如printStackTrace();
}
}
私有类生产者实现Runnable{
@凌驾
公开募捐{
try(streamlines=Files.lines(Path.get(“Path”)){
System.out.println(lines.count());
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
}
我看不出有任何理由不能完成此操作。但是,这不是您实际的代码,也就是说,您没有显示如何处理潜在的IOException
s或filePath
的来源,因此在您没有显示的代码部分中可能会出现一些错误。是的,我刚刚发布了必需的部分,但现在已更新以避免混淆;)我想你的猜测是对的。我刚替换了代码,它就工作了。谢谢因此,我认为这是execute()和submit().get()方法的不同行为之间的结论。需要合理解释原因。@Malith它们是相同的,只有sutmit().get()被阻止,直到值返回。是的,完全正确。不知道为什么它们的行为不同。@Malith如果使用第二节的代码,它也可以打印行。也许你需要先看一些文章。谢谢你的建议。实际上,我不能使用Thread().join()或get(),因为如果有多个任务,它会阻止执行下一个线程。但我找到了根本原因和其他原因。我使用Junit执行代码,Junit运行时退出,而不管子线程是否仍在执行,这导致了这种行为。将ThreadPool shutdown()与Await Termination()结合使用解决了此问题。