【问题标题】:Java - Allow one thread in a method without waitingJava - 在方法中允许一个线程而无需等待
【发布时间】:2021-11-10 00:58:13
【问题描述】:

我有一种情况,我需要实现一个线程安全的方法,该方法一次只能由一个线程执行,并且当该方法由一个线程执行时,所有其他线程都试图执行相同的操作方法不应等待,必须退出该方法。

同步在这里没有帮助,因为线程将等待顺序执行该方法。

我认为我可以通过使用下面的代码使用 ConcurrentHashMap 来实现这一点,但不确定这是否是实现它的完美方式。

Class Test {

private ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>();

    public void execute() {
        
        if (map.putIfApsent("key", new Object()) != null) { // map has value for key which means a thread has already entered.
            return; // early exit
        }
        
        threadSafeMethod();
        map.remove("key");
    }
    
    private void threadSafeMethod() {
        // my code
    }
}

【问题讨论】:

  • 您可以使用AtomicBool 并将其用作标志来确定是否有人在运行线程
  • @MadProgrammer 是的,这看起来是最简单有效的方法

标签: java multithreading concurrency synchronization single-threaded


【解决方案1】:

您可以在不同步的情况下执行此操作,使用布尔值进行比较和交换:

private AtomicBoolean entered = new AtomicBoolean(false);

public void execute() {
   if(entered.compareAndSet(false,true) {
      try {
         method()
      } finally {
         entered.set(false)
      }
   }
}

【讨论】:

    【解决方案2】:

    您可以使用ReentrantLock 并为等待时间指定一个负值。在这种情况下,如果有线程已经在执行代码,调度程序将不会尝试等待。

    // define the lock somewhere as an instance variable
     Lock lock = new ReentrantLock();
    
     try {
            var isAvailable = lock.tryLock(-1, TimeUnit.NANOSECONDS);
            if(isAvailable) {
                System.out.println("do work");
                lock.unlock();
            }
      } catch (InterruptedException e) {
            e.printStackTrace();
      } 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-25
      • 2020-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-26
      • 1970-01-01
      • 2016-06-22
      相关资源
      最近更新 更多