gpt4 book ai didi

Java:Object.wait() 导致执行的主线程从测试返回

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:06:16 25 4
gpt4 key购买 nike

我正在编写一些测试来驱动我的副项目的开发,并且遇到了一些非常奇怪的 Java 行为:

Object.wait() 导致执行的主线程返回并跳过所有以下执行行,但仅在循环中第二次调用它。

我之所以知道这是因为我试图在不使用 Thread.sleep() 的情况下编写测试,因为我认为将这些插入到执行的主线程中通常是不好的做法,尤其是稍后会扩展和扩展的测试成为运行时间非常长的任务。

这是我的测试:

@Test
public void testSendReceiveAll() throws Exception {
for (String s : (ArrayList<String>)testFiles) {
((FakeSendFileApi) sendFileApi).setSender(new InetSocketAddress(LOCALHOST,
LOCALPORT)).setIncomingFileName(s + incrAppend());
PendingFile pendingFile = new PendingFile(TEST_PATH + s, new InetSocketAddress(LOCALHOST,
LOCALPORT));
SendAction sendAction = new SendAction(pendingFile);
Thread sendActionThread = new Thread(sendAction);
synchronized (sendAction){
sendActionThread.start();
sendAction.wait(TIMEOUT_MS);
}

File file = new File(s + fileAppend);
assertTrue(file.exists());
assertTrue(file.isFile());
assertTrue(file.canRead());
assertTrue(file.delete());
}
}

作用说明:遍历所有测试文件并在本地发送和接收它们。有一个在测试中实例化并运行的 SendAction 类:

/**
* Attempts to send the specified file to the specified <code>InetSocketAddress</code>.
* The file's path must be specified completely either absolutely or relatively.
*
* @return true if <code>pendingFile</code> was sent successfully in its entirety.
*/
public synchronized void run() {
try {
ServerSocket serverSocket = new ServerSocket(pendingFile.getSender().getPort());
serverSocket.setSoTimeout(socketTimeoutMillis);
// Blocks until a connection is made on specified socket or until TIMEOUT is reached.
Socket socket = serverSocket.accept();
System.out.println("Sending file " + pendingFile.getFileName());
OutputStream outputStream = socket.getOutputStream();
sendByteArray(new RandomAccessFile(pendingFile.getFileName(), "r"), outputStream);
serverSocket.close();
notifyAll();
} catch (IOException e) {
System.err.println(e); // TODO log error appropriately
}
}

问题:当我 HitTest 的同步块(synchronized block)并启动线程发送,然后等待来自该 sendAction 的通知时,这在循环中第一次起作用。 然而,第二次通过,测试简单地通过并退出对

的调用
sendAction.wait(TIMEOUT_MS);

这只是有时会发生,其他时候不会。我已经放置了 print 语句以查看是否可以在不调试的情况下实现竞争条件,并且它确实发送和接收第一个文件,但并不总是发送和接收第二个文件。当我在 sendAction.wait(TIMEOUT_MS) 之后放置一个 println() 语句时;调用,它永远不会在第二次循环迭代后执行。

什么给了???

最佳答案

等待应该总是在循环中发生。 (有关详细信息,请参阅 Object.wait() 的 javadoc)。

维护一个标记任务完成的标志,并在条件中使用它来守护sendAction.wait()

while(!sendAction.finished) {
sendAction.wait(TIMEOUT_MS);
}

在调用 notifyAll() 之前将“sendAction.finished”设置为 true...并在最后执行此操作。

关于Java:Object.wait() 导致执行的主线程从测试返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21080162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com