代码之家  ›  专栏  ›  技术社区  ›  Ricardo Marimon

如何锁定java方法以保护多个调用

  •  9
  • Ricardo Marimon  · 技术社区  · 16 年前

    public class ReplicatorRunner {
    
           private static Lock lock = new ReentrantLock();
    
           public replicate() {
    
               if (lock.tryLock()) {
                   try {
                       // long running process
                   } catch (Exception e) {                   
                   } finally {
                       lock.unlock();
                   }               
               } else {
                   throw new IllegalStateException("already replicating");
               }
    
           }
    
    }
    
    public class ReplicatorRunnerInvocator {
    
        public void someMethod() {
    
            try {
                ReplicatorRunner replicator = new ReplicatorRunner();
                replicator.replicate();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
    
        }
    
    }
    

    这个 ReplicatorRunner replicate 一次只能运行一个。

    我需要下一个电话失败( 不阻止 )如果该方法已在任何实例上运行。

    5 回复  |  直到 16 年前
        1
  •  4
  •   Matthew Flynn    16 年前

    这看起来不错。tryLock()只会将锁赋给一个线程,所以 synchronized

    去吧。

        2
  •  1
  •   Mark Pope    16 年前

    改变 public replicate() 到 public synchronized replicate()

        3
  •  1
  •   Ricardo Marimon    16 年前

    我最终使用了以下方法:

    public class ReplicatorRunner {
    
           private static Semaphore lock = new Semaphore(1);
    
           public replicate() {
    
               if (lock.tryAcquire()) {
                   try {                              
                       // basic setup                  
                       Thread t = new Thread(new Runnable() {
                           public void run() {
                               try {
                                   // long running process                               
                               } catch Exception (e) {
                                   // handle the exceptions
                               } finally {
                                   lock.release();
                               }
                           }
                       })
                       t.start();
    
                   } catch (Exception e) {
                       // in case something goes wrong
                       // before the thread starts
                       lock.release();
                   }              
               } else {
                   throw new IllegalStateException("already replicating");
               }
    
           }
    
    }
    
    public class ReplicatorRunnerInvocator {
    
        public void someMethod() {
    
            try {
                ReplicatorRunner replicator = new ReplicatorRunner();
                replicator.replicate();
            } catch (IllegalStateException e) {
                e.printStackTrace();
            }
    
        }
    
    }
    
        4
  •  0
  •   crowne    16 年前

    如果不看ReentrantLock的细节,我会想到,这种防止多个同时复制例程的方法将仅限于一个JVM实例。

    如果该类的另一个实例在单独的JVM中启动,那么您可能会遇到麻烦。

        5
  •  0
  •   marcosbeirigo    16 年前

    看一下信号量类 here 或者将该方法标记为已同步 在任何给定时间执行该方法的线程都拥有一个锁,以避免其他线程在其执行结束前调用该方法。
    编辑:如果希望其他线程失败,可以使用 Lock