java - OSX High Sierra 上的 Java 教程揭示了线程问题
问题描述
我一直在关注 cleancoders.com 上的 Java 案例研究
https://cleancoders.com/videos/java-case-study
您还可以在此处找到视频系列:
https://www.safaribooksonline.com/videos/clean-code-applied/9780134843810
围绕第 4-5 集,他们添加了一些同步原语,对我来说只是挂断了。
代码可以在他们的 github 历史中找到:
https://github.com/cleancoders/CleanCodeCaseStudy/tree/187e6129de85ad5d33c23ac98a7063b9b35720c5
提交名称是“第 6 集,有 3 个西红柿”
我正在使用 OSX 10.13.6
使用 Java 1.8
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
与 IntelliJ 社区版 2018.2.4
所以我现在几乎被困住了,因为他们根据这段代码向前推进,而测试只是挂起......
它们在服务对象上同步以强制事件按顺序发生:
有问题的测试代码:
@Test
public void canSendAndReceiveData() throws Exception {
server.start();
Socket s = new Socket("localhost", port);
OutputStream os = s.getOutputStream();
os.write("hello\n".getBytes());
synchronized(readingService) {
readingService.wait();
}
server.stop();
assertEquals("hello", readingService.message);
}
}
然后在服务内部,他们调用'notify()'来释放等待线程,但它永远不会被释放......
public static abstract class TestSocketService implements SocketService {
public void serve(Socket s) {
try {
doService(s);
synchronized(this) { notify(); }
s.close();
} catch(IOException e) {
e.printStackTrace();
}
}
我很困惑......所以任何帮助将不胜感激。
谢谢!
附加说明:
如果我下载完成的项目,它有同样的问题,所以很明显教程不能解决这个错误......
https://github.com/cleancoders/CleanCodeCaseStudy
更新
我找到了一台windows电脑并安装在那里,它没有显示这个问题。所以现在我可能不得不得出结论,这与我正在使用的这台 Mac 有关。它非常快:
2.3 GHz Intel Core i5
8 GB 2133 MHz LPDDR3
也许它能够揭示问题,因为其他计算机速度较慢或者它可能与Java版本有关,无论如何,我能够继续这样做,而不是被阻止。我将更改标题以反映这一点。
解决方案
你有:
synchronized(readingService) {
readingService.wait();
但是您正在通知“this”上的线程您需要通知对象引用 readingService。您所拥有的是通知错误对象的经典案例。
使用“this”来等待/通知通常是个坏主意。很难弄清楚“this”到底指的是什么。我不会去github看其他代码。
如果您可以修改代码,请将 readingService 的引用传递给实现 TestSocketService 的 Class。
推荐阅读
- flutter - Flutter IOS上网
- linux - 如何从 http 请求中阻止端口服务器
- kotlin - 与 Eager 相比,使用延迟初始化有什么好处吗?
- bash - 使用 docker-compose run -rm 时的前缀
- wordpress - 工具,可以找到wordpress网站
- python - 为单元测试修补 python 类构造函数
- unity3d - 如何统一访问切片精灵?
- r - 如何根据自定义顺序对列进行排序?
- typo3 - Powermail (7.4.0) 默认验证码在 TYPO3 9.5.7 中不断失败
- javascript - sendRedirect() 不起作用,可能是因为调用 servlet 的方式(来自 jquery)