gpt4 book ai didi

java - 重新访问空同步块(synchronized block) : data visibility

转载 作者:行者123 更新时间:2023-11-29 05:51:29 25 4
gpt4 key购买 nike

我读了this stackoverflow 主题,结论似乎是一个空的 synchronized block 总是可以通过更好的解决方案来避免。该主题还有一些我不清楚的部分,我会将其整合到我的下面的帖子中。

假设我们有这样一个类:

public class MyThreadClass extends Thread {
private final OtherComponent mOtherComponent;
private final Object mLock = new Object();
private MyHandler mHandler;

public MyCustomThread(OtherComponent otherComponent) {
mOtherComponent = otherComponent;

public void run() {

mHandler = new Handler() {...}

// Other init operations

mOtherComponent.onMyCustomThreadInitialized();

// ... other operations (Looper.loop(), actually)
}

public void sendMessageWithHandler(int what, int arg) {
synchronized (mLock) {}
Message msg = mHandler.obtainMessage(what);
msg.arg1 = arg;
mHandler.sendMessage(msg);
}

public void useHandlerInAnotherWay(...) {
synchronized (mLock) {
// useful code that needs actual mutual exclusion
}
mHandler.sendMessage(...);
}
}

我的应用程序的相关部分按以下方式工作:

  1. 创建并启动了 MyThreadClass 线程。
  2. 作为 mOtherComponent.onMyCustomThreadInitialized() 的间接结果,我的应用程序的另一部分将开始生成其他线程。 (请注意,它们不是从这个调用同步启动的,这就是为什么我说它是间接结果。唯一的一点是,mHandler 在这些其他线程时已经初始化 开始)
  3. 每个其他线程都会调用sendMessageWithHandler(...)一次
  4. 其他线程(即不是上面提到的线程)再次调用 useHandlerInAnotherWay(...),这可能随时发生(在 mOtherComponent.onMyCustomThreadInitialized() 之后) ,当然)。

我的问题:

  1. 如果我是正确的,当从 myThreadClass 之外的其他线程访问 mHandler 时,必须保证最新的数据可见性,因为它不是final 字段。我也不想让它成为 volatile,因为除了这几个 sendMessageWithHandler(..) 调用之外,mHandler 没有被其他人使用没有同步的线程(我不希望 volatile 开销不必要地出现在不需要的地方)。换句话说,当通过 useHandlerInAnotherWay() 从其他线程访问 mHandler 时,同步 与“有用的代码”(即实际上需要成为互斥主题的代码)也保证调用者线程正确地看到 mHandler。然而,在 sendMessageWithHandler(..) 中,代码不需要互斥,所以我决定在 sendMessageWithHandler(...) 的开头放置一个空的同步块(synchronized block).它是否正确?我的问题有更好的解决方案吗?

  2. 我链接到的另一个 stackoverflow 线程有以下答案(它不是被接受的,但被多次投票):

    It used to be the case that the specification implied certain memory barrier operations occurred. However, the spec has now changed and the original spec was never implemented correctly. It may be used to wait for another thread to release the lock, but coordinating that the other thread has already acquired the lock would be tricky.

    这是否意味着空的 synchronized 不再提供内存屏障功能?如果我在线查看有关 synchronized 的 Java 文档,他们会提到所有内存都因此而更新(即线程副本在监视器进入时从“主内存”更新,“主内存”从更新监视器导出处的线程副本)。但是他们没有提到任何关于空 synchronized block 的事情,所以我不清楚。

最佳答案

您可能不需要任何同步。

(thread 1)          (thread 2)

write
|
start thread 2
\
...
|
read

read 保证看到 write


synchronized 的语义是严格执行的,即使它是一个空 block 。

关于java - 重新访问空同步块(synchronized block) : data visibility,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13727753/

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