在下面的课程中,我使用的是singleThreadScheduledExecutor。我的问题是,我是否需要同步访问dummyInt和dummyBoolean?
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class Playground {
/**
* @param args
*/
public static void main(String[] args) {
startThread();
}
private static void startThread() {
ScheduledExecutorService timer = Executors
.newSingleThreadScheduledExecutor();
Runnable r = new Runnable() {
int dummyInt = 0;
boolean dummyBoolean = false;
@Override
public void run() {
dummyInt = dummyInt + 1;
if (dummyBoolean) {
dummyBoolean= false;
} else {
dummyBoolean= true;
}
}
};
timer.scheduleAtFixedRate(r, 0, 100, TimeUnit.MILLISECONDS);
}
}
答案 0 :(得分:3)
不,你没有。只有一个线程访问这些值,因此不需要同步。
答案 1 :(得分:2)
您使用该机制开始的每个线程都将拥有自己定义和实例化的“Runnable”子类的实例。因此,不可能有争用。
答案 2 :(得分:1)
会不会影响性能?嗯,是的,但不是你想象的那么多。现代JIT编译器非常高兴地发现在当前使用中不需要同步,并且几乎消除了编译代码的所有开销 - 但是仍然会有一些开销来检查单线程访问的假设是否仍然存在有效。当然,还有JIT这个的开销。
不同步会不会有害?嗯,可能,如果实现发生了变化,并且单线程访问的假设不再存在 - 并且开发人员进行更改会忽略其更改的后果。
但实际上,在这种情况下,是否可能发生?也许不是 - 所有代码都包含在一个非常小的区域......
我可能会留下一些记录这一假设的评论。如果我在项目中的其他任何地方使用JCIP annotations,我甚至可以将该类注释为@NotThreadSafe。关于这些注释的使用的讨论可以在Brian Goetz的Java Concurrency In Practice书中找到,注释源代码和jar文件可以从书的web site下载。
答案 3 :(得分:0)
你不必把它synchronized
答案 4 :(得分:-1)
不,但可能不会受伤。因为您使用了承诺
的newSingleThreadScheduledExecutor保证执行任务 顺序地,不超过一个 任务将在任何给定时间激活。
但如果您更改了执行程序,请让Runnable离开,以便其他人可以调用它,或者从外部检查值,然后您希望自己同步它。
答案 5 :(得分:-2)
dummyInt = dummyInt + 1;
这个陈述实际上是3个单独的操作:
所以是的,你需要同步这个。一个线程可以读取该值,然后另一个线程执行所有三个操作,并且当第一个线程完成时,该值仅增加1(我希望这是有道理的:P)。dummyBoolean
是类似的。您在if语句中读取它并写入新值。
修改
很抱歉没有正确阅读问题。 根据javadoc,这不应该需要同步。