我的问题是关于它是否可能在Java
中知道线程是否会等待锁定并立即拉出该线程(本身),如果是这种情况,即线程是否要等待锁。
e.g。对于以下理论代码,
public void f() {
synchronized(this) {
//long tasks
}
}
如果Thread-A
已经在长时间synchronized
阻止,Thread-B
进来,则lock
无法立即可用,因此决定撤出(或等待x秒然后拉出out)并再试一次。
我认为通过synchronized
块进行原始锁定是不可能的,但只是希望知道 - 如果一个线程不愿意进入WAIT
状态或者如果可能强行拉出一个线程WAIT
州。
我的意思是,是否可以在Thread-B
OR Thread-A
代码中为此逻辑编写内容?
答案 0 :(得分:4)
是的,可以使用java.util.concurrent
包中的原语。即您可以使用ReentrantLock
基本上模拟标准synchronized
块,但也可以使用tryLock
方法进行超时。
ReentrantLock lock = new ReentrantLock();
public void f() {
try {
if (lock.tryLock(10, TimeUnit.SECONDS)) {
try {
//you have the lock here...
} finally {
//unlock
lock.unlock();
}
} else {
//pull-out
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
答案 1 :(得分:2)
您可以使用Lock objects
使用乐观语义。像tryLock
这样的东西:
只有在调用时它是空闲的时才获取锁。
获取锁定(如果可用)并立即返回值true。如果锁定不可用,则此方法将立即返回值false。
文档示例:
Lock lock = ...;
if (lock.tryLock()) {
try {
// manipulate protected state
} finally {
lock.unlock();
}
} else {
// perform alternative actions
}
答案 2 :(得分:0)
一种选择是使用Object.wait(long timeout)
。线程将在指定的时间段后或在通知(通过Object.notify()
)时退出等待。
因此,长时间运行的线程可以在完成之前调用notify()
来表示等待线程继续(并且不要等到超时到期)。
要从另一个线程中踢出一个线程,你可以在持有锁的线程上调用Thread.interrupt()
(假设该线程中没有忽略InterruptedException
);这种做法有点极端,我不认为这是去这里的方式。
这一切都是使用"原语"同步工具。您可以使用java.util.concurrent.Lock
和Condition
来实现相同(和更多)。