【问题标题】:Java one critical section multiple semaphoresJava 一个临界区多个信号量
【发布时间】:2015-12-12 15:02:56
【问题描述】:

我需要知道,是否有一些框架可以为我提供这种功能。我在一个方法中有一个关键部分,我需要很少的其他方法等到这个关键部分被执行和完成。如果临界区不活跃,这些方法应该可以流畅地工作。

如果只有在信号量方法中没有线程时才进入临界区。

如:

public class Worker {

    private Critical critical = null;
    private CriticalDependent dep1 = null; 
    private CriticalDependent dep2 = null;

    public Worker() {

        critical = new Critical();
        dep1 = critical.registerDependent();
        dep2 = critical.registerDependent();

    }
    public void critical() {
         critical.enter();
         critical.waitForClearToGo();

         // protected unique code
         // change resource handle etc

         critical.exit();
    }

    public void dependent1() {
         critical.checkWaitAndUnsetClearToGo(this.dep1);

         // some dependent code
         // use resource handle

         critical.setClearToGo(this.dep1);
    }

    public void dependent2() {
         critical.checkWaitAndUnsetClearToGo(this.dep2);

         // some dependent code
         // use resource handle

         critical.setClearToGo(this.dep2);
    }
}

我可以想出一些解决方案,但我更喜欢使用现有的框架。而且我找不到现有的。提前谢谢你。

【问题讨论】:

标签: java multithreading frameworks semaphore


【解决方案1】:

使用标准的 Java Semaphore

【讨论】:

  • 拜托,你能给我一些提示吗?
  • 你检查链接了吗?
  • 是的,我已经检查过了 - 我不确定它是否适合我的场景。对我来说,提供的代码不像你那么简单。我会检查更多的例子......
  • 由于许可计数是整数而不是对象...我不知道如何在我的场景中使用它。我对我的场景做了一些细微的改动,以提供更多关于我真正需要的信息。我不认为信号量单独可以帮助我。
【解决方案2】:

正如 Erik 所说,您可以使用 Java 的 Semaphore 来做到这一点。 但是你需要一个有 2 个许可的,这样你的 2 个依赖方法可以同时运行,但是临界区会阻塞两个依赖方法。

Semaphore semaphore = new Semaphore(2, true);  // Make it fair, so critical section won't wait unnecessarily

public void critical() {
    semaphore.acquire(2); // Blocks both dependents, waiting if they're not available
    ...
    semaphore.release(2);
}

public void dep1() {
    semaphore.acquire(); // Blocks only if critical() has both permits
    ...
    semaphore.release();
}

public void dep2() {
    semaphore.acquire(); // Ditto, dep1() can have the other permit
    ...
    semaphore.release();
}

【讨论】:

  • 对不起,我刚刚测试过,这个例子不能像我希望的那样工作。此代码允许在关键期间运行 dep1 和 dep2。要么信号量不适合这个,要么你提供了错误的例子,或者我犯了重写它的错误?
  • Start ... thrd 1 dep1 System time=1449939961641 thrd 2 dep1 System time=1449939961641 thrd 2 dep2 System time=1449939961891 thrd 1 dep2 System time=1449939961891 thrd 2 result 0 : 0 Critical enter , System time=1449939962141 thrd 1 result 0 : 0 thrd 1 dep1 System time=1449939962141... this should not happen if it worked Critical done , System time=1449939963141
  • 我从我的测试代码中发布了转储。很明显 dep1 在关键期间被调用并执行...所以...?
  • 那你就搞错了。自然,所有线程都应该在同一个 Semaphore 对象上工作,因此如果您有多个 Worker 类,则需要重新考虑您的方法。该示例非常适用于单个 Worker,其中有 3 个线程在其上工作。如果您需要更多线程,可以将许可增加到 1000 之类的过多,并确保 critical() 获取所有这些。
  • 奇怪。我制作了包含信号量的类测试,实现了上述所有三种方法并具有入口点。 Dep1 和 Dep2 返回整数,每次调用 critical 时都会增加一。这些方法的作用与您描述的完全一样。类 test 具有内部类扩展线程,其构造函数包含对类 test 和 run 方法的引用,其中它在循环中调用 dep1、dep2。在入口点我创建测试和两个线程,等到线程完成。结果如上所示 - 当输入关键时,线程愉快地访问 dep1 & dep2。
猜你喜欢
  • 2018-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 2015-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多