我已经编写了一个使用 Java 流的方法,它简单地遍历对象列表并在满足特定条件时返回 true/false
Java 方法:
boolean method(SampleObj sampleObj) {
List testList = invokeSomeMethod();
int result = testList
.parallelStream()
.filter(listObj -> (listObj.getAttr() = 1))
.count(listObj -> listObj.isAttr4());
return (result > 10);
}
我也为此编写了一个 Mock 测试用例。当我执行测试用例时,测试成功,但是我收到项目自定义错误,指出所有创建的线程都没有关闭。
我什至尝试将流与 try-with-resources 一起使用,但 noo 没有帮助。
模拟测试:
@Test
public void testSomeMethod() {
SampleObj sampleObj1 = new SampleObj(10, 20, 30, true);
SampleObj sampleObj2 = new SampleObj(10, 20, 30, true);
SampleObj sampleObj3 = new SampleObj(10, 20, 30, false);
SampleObj sampleObjTest = new SampleObj(10, 20, 30, true);
List<SampleObj> testList = new ArrayList<SampleObj>();
testList.add(sampleObj1);
testList.add(sampleObj2);
testList.add(sampleObj3);
when(mockedAttribute.invokeSomeMethod()).thenReturn(nodeList);
ClassToBeTested classTest = createGenericMockRules();
Assert.assertTrue(classTest.method(sampleObjTest));
}
附言我已经调试以确认在调用 invokeSomeMethod() 时,我的模拟 testList 已返回。
据我所知,Java 流在内部关闭它创建的线程。 我是否错误地实现了这一点?
最佳答案
Java 流不创建线程,因此不处理线程。他们在内部使用线程池;未指定但众所周知它是 common pool of the Fork/Join framework .
使用线程池的全部目的是让池管理线程,而不是为每个作业创建和处理线程。创建和销毁线程与成本相关,当多个作业随后入队时应避免这种情况。特别是线程的创建时间会增加作业的执行时间,如果没有现有的线程来拾取它的话。换句话说,线程的生命周期比作业长是正常的,也是有意为之的。他们正在等待可能到来的新工作。
class documentation of ForkJoinPool状态:
A static commonPool() is available and appropriate for most applications. The common pool is used by any ForkJoinTask that is not explicitly submitted to a specified pool. Using the common pool normally reduces resource usage (its threads are slowly reclaimed during periods of non-use, and reinstated upon subsequent use).
除了“缓慢”之外,它没有指定线程在被回收之前必须空闲的时间,因此它甚至可能因实现而异。对于当前的实现,甚至不可能用超时来表示,因为池会减少线程的数量,而不是在超时后终止所有空闲线程,因此剩余的线程将再次等待,增加超时,直到池再次缩小大小,直到没有空闲线程为止。换句话说,池中的线程越多,当所有线程都空闲时,回收最后一个线程所需的时间就越长。
您可以通过
强制您的测试等待所有线程结束while(ForkJoinPool.commonPool().getPoolSize()>0)
LockSupport.parkNanos(1000);
但这会显着增加测试的执行时间,例如谈论八个核心/线程的一分钟的量级。更好的解决方案是重新考虑您的“项目自定义错误”检查,即不应该认为您的代码对内部使用的池创建的线程负责。
否则,您在使用时可能会遇到类似的错误,例如异步I/O等
关于Java Parallel Streams 关闭线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42520698/
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
下面的代码在我第一次运行它时就可以正常工作:require'rubygems'require'spreadsheet'book=Spreadsheet.open'/Users/me/myruby/Mywks.xls'sheet=book.worksheet0row=sheet.row(1)putsrow[1]book.write'/Users/me/myruby/Mywks.xls'当我再次运行它时,我会收到更多消息,例如:/Library/Ruby/Gems/1.8/gems/spreadsheet-0.6.5.9/lib/spreadsheet/excel/reader.rb:11
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
我是ruby的新手,我认为重新构建一个我用C#编写的简单聊天程序是个好主意。我正在使用Ruby2.0.0MRI(Matz的Ruby实现)。问题是我想在服务器运行时为简单的服务器命令提供I/O。这是从示例中获取的服务器。我添加了使用gets()获取输入的命令方法。我希望此方法在后台作为线程运行,但该线程正在阻塞另一个线程。require'socket'#Getsocketsfromstdlibserver=TCPServer.open(2000)#Sockettolistenonport2000defcommandsx=1whilex==1exitProgram=gets.chomp
一段时间以来,我一直在使用open_uri下拉ftp路径作为数据源,但突然发现我几乎连续不断地收到“530抱歉,允许的最大客户端数(95)已经连接。”我不确定我的代码是否有问题,或者是否是其他人在访问服务器,不幸的是,我无法真正确定谁有问题。本质上,我正在读取FTPURI:defself.read_uri(uri)beginuri=open(uri).readuri=="Error"?nil:urirescueOpenURI::HTTPErrornilendend我猜我需要在这里添加一些额外的错误处理代码...我想确保我采取一切预防措施来关闭所有连接,这样我的连接就不是问题所在,但是我
我有一个使用PDFKit呈现网页的pdf版本的Rails应用程序。我使用Thin作为开发服务器。问题是当我处于开发模式时。当我使用“bundleexecrailss”启动我的服务器并尝试呈现任何PDF时,整个过程会陷入僵局,因为当您呈现PDF时,会向服务器请求一些额外的资源,如图像和css,看起来只有一个线程.如何配置Rails开发服务器以运行多个工作线程?非常感谢。 最佳答案 我找到的最简单的解决方案是unicorn.geminstallunicorn创建一个unicorn.conf:worker_processes3然后使用它:
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d
所以,Ruby1.9.1现在是declaredstable.Rails应该与它一起工作,并且正在慢慢地将gem移植到它。它具有native线程和全局解释器锁(GIL)。自从GIL到位后,原生线程是否比1.9.1中的绿色线程有任何优势? 最佳答案 1.9中的线程是原生的,但它们被“放慢了速度”,一次只允许一个线程运行。这是因为如果线程真的并行运行,它会混淆现有代码。优点:IO现在在线程中是异步的。如果一个线程阻塞在IO上,那么另一个线程将继续执行直到IO完成。C扩展可以使用真正的线程。缺点:任何非线程安全的C扩展都可能存在使用Thre
使用ruby的watir测试网络应用程序时,浏览器最后会保持打开状态。网上的一些建议是,要进行真正的单元测试,您应该在每次测试时(在拆卸调用中)打开和关闭浏览器,但这很慢而且毫无意义。或者他们做这样的事情:defself.suites=superdefs.afterClass#Closebrowserenddefs.run(*args)superafterClassendsend但这会导致摘要输出不再显示(诸如“100次测试、100次断言、0次失败、0次错误”之类的内容仍应显示)。我怎样才能让ruby或watir在我的测试结束时关闭浏览器? 最佳答案
我在一个ruby文件中有一个函数可以像这样写入一个文件File.open("myfile",'a'){|f|f.puts("#{sometext}")}这个函数在不同的线程中被调用,使得像上面这样的文件写入不是线程安全的。有谁知道如何以最简单的方式使这个文件写入线程安全?更多信息:如果重要的话,我正在使用rspec框架。 最佳答案 您可以通过File#flock给锁File.open("myfile",'a'){|f|f.flock(File::LOCK_EX)f.puts("#{sometext}")}