【发布时间】:2011-11-10 22:27:39
【问题描述】:
我一直认为在实现 Runnable 的 java 类中同步 run 方法是多余的。 我想弄清楚人们为什么这样做:
public class ThreadedClass implements Runnable{
//other stuff
public synchronized void run(){
while(true)
//do some stuff in a thread
}
}
}
这似乎是多余和不必要的,因为他们正在为另一个线程获取对象的锁。或者更确切地说,他们明确表示只有一个线程可以访问 run() 方法。但是既然是run方法,那它本身不就是自己的线程吗?所以只有它自己可以访问,不需要单独的锁机制?
我在网上找到了一个建议,通过同步 run 方法,您可能会创建一个事实上的线程队列,例如这样做:
public void createThreadQueue(){
ThreadedClass a = new ThreadedClass();
new Thread(a, "First one").start();
new Thread(a, "Second one, waiting on the first one").start();
new Thread(a, "Third one, waiting on the other two...").start();
}
我永远不会亲自这样做,但这会引发一个问题,即为什么有人会同步 run 方法。 任何想法为什么或为什么不应该同步 run 方法?
【问题讨论】:
-
队列有问题(对象监视器不公平,第二个线程可能在第一个线程之前运行),我能想象的唯一原因是确保当一个可运行对象被提交两次时一个执行器/线程它不会创建比赛
-
@irreputable 我的教授举了一个例子。我个人永远不会——除非我在等着看是否有任何尚未被指出的绝妙理由这样做。
-
@ratchet 好点。我猜你只希望同步运行它,如果有一个奇怪的原因导致另一个线程可能在同一个对象上执行。但即便如此,我认为我会以不同的方式解决它。
-
@MHP 一个原子布尔 hasRun 和一个
if(!hasRun.CompareAndSwap(false,true))return;在运行中更好(因为它不会阻塞线程并确保运行只执行一次)但需要额外的代码和单独的 var -
这很奇怪。我有点担心你得到的教导。你显然可以看穿迷雾,但你班上的每个人可能都不是这样。当你必须做作业时,这是一个令人讨厌的情况:你做正常的事情还是你的教授做的事情?
标签: java multithreading synchronization synchronized runnable