我有这个遗留的伪代码:
public class Wrapper {
private volatile Sink sink;
public synchronized void flushSink() {
if (sink != null) {
synchronized (sink) {
sink.flush();
}
}
}
public void close() throws IOException {
var sink = this.sink;
if (sink != null) {
sink.receivedLast();
}
}
}
我的问题是关于嵌套同步
块。
据我了解,在这种情况下提到的块是多余的,就好像两个线程同时调用 flushSink(),
那么一次只有一个线程可以访问私有字段接收器
。因此,代码可以简化为
public class Wrapper {
private volatile Sink sink;
public synchronized void flushSink() {
if (sink != null) {
sink.flush();
}
}
}
有可能进一步消除racy读取到
public class Wrapper {
private volatile Sink sink;
public synchronized void flushSink() {
var sink = this.sink;
if (sink != null) {
sink.flush();
}
}
}
所以我的问题是,这种重构在同步和JMM方面是否正确,如果正确(或者不正确)-是否有基于JCStress的测试证明了这一点?
据我所知,在这种情况下,提到的块是多余的,就像两个线程同时调用flushSink(),那么一次只有其中一个可以访问私有字段接收器。因此,代码可以简化为
只要代码中没有其他地方可以在同步块中访问< code>sink,它就是多余的。
例如,如果将< code>close()方法更改为以下内容,
public void close() throws IOException {
var sink = this.sink;
if (sink != null) {
synchronized(sink) {
sink.receivedLast();
}
}
}
那么flushSink
() 中的同步块不会是无用的,因为它可以确保 receivedLast
() 和 flush()
不会同时被调用。
问题内容: 我正在查看包含同步方法的第三方库中的一些代码,在此方法中,有一个锁定在实例变量上的同步块。与此类似: 这有意义吗?如果是这样,在同步方法中使用同步语句有什么好处? 鉴于同步方法锁定了整个对象,对我来说似乎是多余的。在使用非私有的实例变量时,这种方法是否有意义? 问题答案: 在您的示例中,该方法 同时 锁定了和的实例。其他方法可能仅锁定对象的实例 或 对象。 因此,是的,这完全取决于他们
问题内容: 我在Heinz Kabutz的 Java专家 通讯版本中看到了这一点,尽管Kabutz博士的文章的其余部分(乃至全部)都得到了很好的解释和详细说明,但他似乎掩盖了这段代码的作用,或更重要的是,它的意义是: 嵌套块的含义是什么?这如何影响尝试执行的不同线程? 问题答案: 有两个可能需要注意的问题 如果使用等待/通知,嵌套锁很容易导致死锁。这是为什么的解释。http://tutorials
所以我写了这个服务器脚本,它应该接收一个用户名,然后继续其他一些代码。但是我收到了这个错误: "OSError:[WinError 10057]不允许发送或接收数据的请求,因为套接字未连接,并且(当使用sendto调用在数据报套接字上发送时)未提供地址" 我的理论是服务器和客户端没有同步,所以服务器认为它没有收到消息。如何改进我的代码,以便服务器实际接收消息?(我试过尝试块) 我的代码: sock
请看下面给我带来麻烦的方法: 然后是run方法:
我正在处理来自TCP套接字的大量事件(每秒10个套接字),因此我使用多线程来处理这些事件。 大多数情况下,这是正确的,但有时会出现这些事件的雪崩,有时我会得到一个ConcurrentModificationException: 12-10 14:08:42.071:E/AndreidRuntime(28135):致命例外:线程-369 12-10 14:08:42.071:E/AndreidRun
是否可以调用一个异步方法,以便它从一个同步的方法异步运行?我不关心它挂起同步调用程序直到它返回,而是希望该方法被异步调用。