现在,我知道我可以使用某种信号量来实现这一目标。但我的问题是让两个线程都能访问这个信号量的正确方法。
我可以创建一个新的静态变量/方法:
public class SharedSemaphore
{
private static Semaphore s = new Semaphore (1, true);
public static void acquire () {
s.acquire();
}
public static void release () {
s.release();
}
}
这会起作用(对吗?)但这似乎不是正确的做法。因为,线程现在可以访问信号量,而无需引用它。这种事情似乎不是一个好的编程实践。我错了吗?
更新
我重新命名了两个方法performTask来获取,另一个方法被释放,因为我觉得这会分散实际问题。
答案 0 :(得分:2)
我认为,你可以制作performSystemTask
方法synchronized
,这就足够了。
答案 1 :(得分:0)
如果线程应该一个接一个地运行,他们需要一个管理器。我会将它们包装到另一个类中,甚至是另一个线程类。
public class wrapperThread extends Thread {
public void run() {
Worker1Thread myThread = new Worker1Thread();
myThread.start();
myThread.join();
Worker2Thread myThread = new Worker2Thread();
myThread.start();
myThread.join();
}
}
这是我能想到的最安全,最干净的方式。
如果它们根本不应该同时运行,那么它们应该是同一个线程。
答案 2 :(得分:0)
我看到你让你的信号量变得公平。所以我想你关心订单执行这些“系统任务”?然后,在我看来,依靠线程的有序到达是非常脆弱和危险的。如果您使用synchronized
关键字,也会出现此问题。
我说你应该使用CountdownLatch
代替。
class TaskOrganizer {
private final CountdownLatch firstTask = new CountdownLatch(1);
public void firstTaskIsDone(){
firstTask.countDown();
}
public void permissionForSecondaryTask(){
firstTask.await();
}
}
如果你不能将TaskOrganizer
个对象传递给你的线程,那么我想让它静态是可以的,但通常最好将实例传递给你的线程(好吧,确切地说是Runnables)。你永远不知道你是否需要2个TaskOrganizers。如果您使用过static
,那么事情就不会像以前那样干净。
我猜这很明显,但是一个线程调用firstTaskIsDone()
,另一个线程阻塞直到完成,调用permissionForSecondaryTask();
。如果你有大量的任务来组织大量的线程,你可能想推出Phaser
(计划出现在JDK 7中,后端可用http://gee.cs.oswego.edu/dl/concurrency-interest/)。