如果检测到互斥,则停止当前线程

时间:2018-01-02 16:51:57

标签: java android multithreading java-threads android-thread

在我的android应用程序中,我的一个MODEL类中有一个特定的方法,这个方法总是从一个不同于UI线程的单独线程调用。

AlarmManger 会定期运行此方法,并且用户还可以选择从UI 运行此方法 。 (AlarmManger操作和UI操作从主应用程序UI线程以外的单独线程调用此方法。)

我只是不想允许从UI和AlarmManger同时运行此方法。

当然我可以 Synchronize 这个方法,并保证一个线程的执行方法。但那个 是我想要的。

如果已经执行了该方法,我想抛出异常并停止第二个线程(可能是UI调用或AlarmManager,具体取决于具体情况)。因此,我可以通知用户已取消操作,因为找到了另一个正在运行的实例(AlarmManger或表单UI)。

我可以问一下这种情况的最佳方法。感谢

2 个答案:

答案 0 :(得分:1)

我从你的问题做出以下假设:

  1. 您希望保证方法上的互斥,但如果存在争用,则返回(表示该方法未执行),不阻止该线程。
  2. 您需要可重用的模型类的实例(例如,假设一旦线程退出该方法,其他一些线程可以再次调用)
  3. 为此,最简单的选项可能是into_inner。像这样的东西(代码没有编译或测试。)

    class MyClass {
        private final ReentrantLock lock = new ReentrantLock();
        public void theMethod() {
            if(!lock.tryLock()) {
                throw new IllegalStateException("Running already");
            }
            try {
                // do stuff
            } finally {
                lock.unlock(); 
            }
        }
    }
    

    抛出异常以表示正在执行该方法意味着通过异常执行流控制,这不是一个好习惯。除非你有充分的理由保留例外,否则我建议这样做:

    class MyClass {
        private final ReentrantLock lock = new ReentrantLock();
        public boolean theMethod() {
            if(!lock.tryLock()) {
                return false;
            }
            try {
                doStuff();
            } finally {
                lock.unlock(); 
            }
            return true;
        }
    }
    

    返回值表示方法是否可以运行,因此调用者可以做出相应的反应。

    如果上面的(2)不适用(也就是说,你只想运行一次方法并确保它再也不会被执行),那么你可以这样做:

    class MyClass {
        private final AtomicBoolean hasExecuted = new AtomicBoolean(false);
        public boolean theMethod() {
            if(!hasExecuted.compareAndSet(false, true) {
                return false; // or throw an exception
            }
            doStuff();
            return true;
        }
    }
    

    我希望有所帮助。

答案 1 :(得分:0)

为什么不使用信号量?您甚至可以使用Java one