可以以编程方式拉出简单的WAIT情况吗?

时间:2016-01-25 06:54:40

标签: java multithreading

我的问题是关于它是否可能在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代码中为此逻辑编写内容?

3 个答案:

答案 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.LockCondition来实现相同(和更多)。