gpt4 book ai didi

java - 在这种情况下是否足够 volatile ?

转载 作者:行者123 更新时间:2023-12-03 12:46:28 25 4
gpt4 key购买 nike

下面是我的应用程序的启动/停止过程,启动/停止代码由单线程 ThreadPoolExecutor 处理,所以我保证只有一个线程可以同时处于 Activity 状态。

我问的是 isRunning 变量。使变量 volatile 足够了吗?变量将从不同的线程访问(读取/修改)(但同时只有一个!)

编辑:添加了变量读取(startProcedure()stopProcedure() 的开头)。我忘记了那部分,我很抱歉。

编辑2:我认为可能很难注意到,但是 startProcedure()stopProcedure() 是用于创建 startQuerystopQuery< 的函数 - 线程使用的 Runnable。

public final class Work {

private static final ThreadPoolExecutor processor = new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(1),
new ThreadPoolExecutor.DiscardPolicy());
private static final Runnable startQuery = Work::startProcedure,
stopQuery = Work::stopProcedure;

private static boolean isRunning = false;

private Work() {}

private static void startProcedure() {
if (isRunning) return;
isRunning = true;
//<some code>
}

private static void stopProcedure() {
if (!isRunning) return;
//<some code>
isRunning = false;
}

//------Public API

public static void start() {
processor.execute(startQuery);
}

public static void stop() {
processor.execute(stopQuery);
}

}

最佳答案

首先,volatile 与“线程安全”关系不大。 volatile 是关于可见性 及其提供的保证;具体来说,它围绕“先于发生”原则工作(不过我不会深入探讨)。

您的情况有点有趣:您只有一个线程。所以真正的问题是,作为 start 方法的一部分完成的操作是否对下一个 stop 方法可见?换句话说,ThreadPoolExecutor::execute 是否提供任何可见性保证?

在我看来答案是:是的而且你根本不需要 volatile。 ExecutorServiceThreadPoolExecutor 实现说:

Memory consistency effects: Actions in a thread prior to the submission of a Runnable or Callable task to an ExecutorService happen-before any actions taken by that task...

我对此的解释是:在开始 线程中完成的操作将先于在停止 线程中完成的操作。但是只有在 startstop 被调用(并等待)后才能做出这种保证 - 就像在你的例子中一样。一旦更改内部实现,这将不起作用。

关于java - 在这种情况下是否足够 volatile ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63860881/

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