Java - 允许方法中有一个线程无需等待
Java - Allow one thread in a method without waiting
我有一种情况需要实现一个线程安全的方法,该方法一次只能由一个线程执行,并且当该方法由一个线程执行时,所有其他线程都试图执行相同的方法不应该等待,必须退出该方法。
同步在这里无济于事,因为线程将等待顺序执行该方法。
我认为我可以通过使用以下代码使用 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
}
}
您可以使用 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();
}
您可以在没有同步的情况下执行此操作,使用布尔值进行比较和交换:
private AtomicBoolean entered = new AtomicBoolean(false);
public void execute() {
if(entered.compareAndSet(false,true) {
try {
method()
} finally {
entered.set(false)
}
}
}
我有一种情况需要实现一个线程安全的方法,该方法一次只能由一个线程执行,并且当该方法由一个线程执行时,所有其他线程都试图执行相同的方法不应该等待,必须退出该方法。
同步在这里无济于事,因为线程将等待顺序执行该方法。
我认为我可以通过使用以下代码使用 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
}
}
您可以使用 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();
}
您可以在没有同步的情况下执行此操作,使用布尔值进行比较和交换:
private AtomicBoolean entered = new AtomicBoolean(false);
public void execute() {
if(entered.compareAndSet(false,true) {
try {
method()
} finally {
entered.set(false)
}
}
}