简体   繁体   English

使用tryLock()以及wait()和notify()/ notifyAll()

[英]using tryLock() together with wait() and notify()/notifyAll()

I'm new to threading and I'm trying to do a hybrid approach here. 我是线程技术的新手,正在这里尝试一种混合方法。 I have below code. 我有下面的代码。

if(lock.tryLock())
{
    try
    {
        //do some actions
        lock.notifyAll(); // error throwing line
    }
    finally
    {
        lock.unlock();
    }
}

If I run the program like this Illegal monitor exception is thrown at that error throwing line. 如果我像这样运行程序,则会在该错误引发行引发非法监视器异常。 but if I call inside a synchronized block like below it works. 但是如果我在下面的同步块中调用它会起作用。

if(lock.tryLock())
{
    try
    {
        //do some actions

        synchronized ( lock )
        {
            lock.notifyAll(); 
        }
    }
    finally
    {
        lock.unlock();
    }
}

My problem is since I have tryLock to true, doesn't it mean that I have already got the lock and I can safely call wait() and notify() methods? 我的问题是,因为我将tryLock设置为true,这是否意味着我已经获得了锁并且可以安全地调用wait()和notify()方法? Thanks in advance.. 提前致谢..

Forget the "hybrid approach" here, this doesn't work. 在这里忘记“混合方法”,这是行不通的。

Every object has an implicit lock. 每个对象都有一个隐式锁。 That includes objects of Lock classes like ReentrantLock. 其中包括诸如ReentrantLock之类的Lock类的对象。 Calling wait and notify always uses the implicit lock, these methods don't use the locking capabilities of the Lock object you're calling them on. 调用wait and notify始终使用隐式锁,这些方法不使用您要对其进行调用的Lock对象的锁定功能。 The wait, notify, and notifyAll methods are declared in Object as native and final. 在对象中,wait,notify和notifyAll方法被声明为本地方法和最终方法。

To get wait and notify to work you'd have to synchronize on the lock object, and locking done by methods like tryLock would be irrelevant, this would end up as functionally equivalent to final Object lock = new Object(); 为了获得等待并通知工作,您必须在锁定对象上进行同步,而通过tryLock之类的方法进行的锁定将是无关紧要的,最终在功能上等同于final Object lock = new Object(); , just more confusing. ,只会更加令人困惑。

Lock objects have their own equivalents, if you are using a java.util.concurrent.locks.Lock then get a condition from the lock, and call await (which is the equivalent of wait) and signal/signalAll (the equivalent of notify/notifyAll). 锁对象具有它们自己的等效项,如果您使用的是java.util.concurrent.locks.Lock然后从锁java.util.concurrent.locks.Lock获取一个条件,然后调用await(等效于wait)和signal / signalAll(等效于notify / notifyAll)。

With Lock objects you can have multiple conditions, allowing you to signal subsets of threads waiting for the lock. 使用Lock对象,您可以具有多个条件,从而允许您发信号通知等待锁定的线程子集。 As a consequence you don't need signalAll anywhere near as much as implicit-locking code needs notifyAll. 因此,您几乎不需要隐式锁定代码需要notifyAll的任何地方的signalAll。

For example, if you look at how ArrayBlockingQueue is implemented, it uses ReentrantLock, and there's one condition for consumers and another condition for producers: 例如,如果您查看ArrayBlockingQueue的实现方式,它使用ReentrantLock,那么对于使用者来说有一个条件,对于生产者来说有另一个条件:

/** Main lock guarding all access */
final ReentrantLock lock;

/** Condition for waiting takes */
private final Condition notEmpty;

/** Condition for waiting puts */
private final Condition notFull;

constructed with

public ArrayBlockingQueue(int capacity, boolean fair) {
    if (capacity <= 0)
        throw new IllegalArgumentException();
    this.items = new Object[capacity];
    lock = new ReentrantLock(fair);
    notEmpty = lock.newCondition();
    notFull =  lock.newCondition();
}

The equivalent code using an implicit lock would have to call notifyAll to avoid losing notifications because we don't know whether the notified thread will be a producer or a consumer, but with separate conditions we know which type of thread will get notified. 使用隐式锁的等效代码必须调用notifyAll以避免丢失通知,因为我们不知道被通知的线程是生产者还是使用者,但是在单独的条件下,我们知道将通知哪种线程。 The dequeueing code, for example, calls signal on the notFull condition, waking up at most one thread: 例如,出队代码在notFull条件下调用信号,最多唤醒一个线程:

/**
 * Extracts element at current take position, advances, and signals.
 * Call only when holding lock.
 */
private E dequeue() {
    // assert lock.getHoldCount() == 1;
    // assert items[takeIndex] != null;
    final Object[] items = this.items;
    @SuppressWarnings("unchecked")
    E x = (E) items[takeIndex];
    items[takeIndex] = null;
    if (++takeIndex == items.length)
        takeIndex = 0;
    count--;
    if (itrs != null)
        itrs.elementDequeued();
    notFull.signal();
    return x;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java 中的线程 | 等待(),通知()和通知所有() - Threads in Java | wait(), notify() and notifyAll() 为什么等待,通知和notifyAll方法都在Object Class中? - Why wait ,notify and notifyAll Methods are in Object Class? 用wait,notify和notifyAll替换Await,Signal,SignalAll - Replace Await, Signal, SignalAll with wait,notify and notifyAll 为什么等待/通知/通知所有方法在 java 中不同步? - why wait/notify/notifyAll methods are not synchronized in java ? 在synchronized语句中的wait(),notify()和notifyAll() - wait(), notify() and notifyAll() inside synchronized statement 调用wait(),notify()或notifyAll()时如何获得相同的监视器? - how to get same monitor when calling wait() ,notify() or notifyAll()? notify和notifyall显示奇怪的行为以等待多个线程 - notify and notifyall showing weird behavior to wait of multiple threads 通过使用notify代替notifyAll来减少线程竞争 - Reduce thread competition by using notify in place of notifyAll 为什么在 java 中使用 wait()、notify()、notifyAll() 时,使用这部分代码的线程必须是唯一拥有它的监视器的线程? - Why when using wait( ) , notify( ) , notifyAll( ) in java the thread using this part of code must be the only thread that own it's monitor? ruby线程编程,ruby相当于java wait / notify / notifyAll - ruby thread programming , ruby equivalent of java wait/notify/notifyAll
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM