Search in sources :

Example 21 with Condition

use of java.util.concurrent.locks.Condition in project kafka by apache.

the class BufferPoolTest method testCleanupMemoryAvailabilityWaiterOnInterruption.

/**
     * Test if the  waiter that is waiting on availability of more memory is cleaned up when an interruption occurs
     */
@Test
public void testCleanupMemoryAvailabilityWaiterOnInterruption() throws Exception {
    BufferPool pool = new BufferPool(2, 1, metrics, time, metricGroup);
    long blockTime = 5000;
    pool.allocate(1, maxBlockTimeMs);
    Thread t1 = new Thread(new BufferPoolAllocator(pool, blockTime));
    Thread t2 = new Thread(new BufferPoolAllocator(pool, blockTime));
    // start thread t1 which will try to allocate more memory on to the Buffer pool
    t1.start();
    // sleep for 500ms. Condition variable c1 associated with pool.allocate() by thread t1 will be inserted in the waiters queue.
    Thread.sleep(500);
    Deque<Condition> waiters = pool.waiters();
    // get the condition object associated with pool.allocate() by thread t1
    Condition c1 = waiters.getFirst();
    // start thread t2 which will try to allocate more memory on to the Buffer pool
    t2.start();
    // sleep for 500ms. Condition variable c2 associated with pool.allocate() by thread t2 will be inserted in the waiters queue. The waiters queue will have 2 entries c1 and c2.
    Thread.sleep(500);
    t1.interrupt();
    // sleep for 500ms.
    Thread.sleep(500);
    // get the condition object associated with allocate() by thread t2
    Condition c2 = waiters.getLast();
    t2.interrupt();
    assertNotEquals(c1, c2);
    t1.join();
    t2.join();
    // both the allocate() called by threads t1 and t2 should have been interrupted and the waiters queue should be empty
    assertEquals(pool.queued(), 0);
}
Also used : Condition(java.util.concurrent.locks.Condition) Test(org.junit.Test)

Example 22 with Condition

use of java.util.concurrent.locks.Condition in project caffeine by ben-manes.

the class NonReentrantLockTest method lock_error.

@Test(dataProvider = "lock")
public void lock_error(NonReentrantLock lock) {
    Condition condition = Mockito.mock(Condition.class);
    try {
        lock.hasWaiters(condition);
        Assert.fail();
    } catch (IllegalArgumentException e) {
    }
    try {
        lock.getWaitQueueLength(condition);
        Assert.fail();
    } catch (IllegalArgumentException e) {
    }
    try {
        lock.getWaitingThreads(condition);
        Assert.fail();
    } catch (IllegalArgumentException e) {
    }
    try {
        lock.sync.tryRelease(1);
        Assert.fail();
    } catch (IllegalMonitorStateException e) {
    }
}
Also used : Condition(java.util.concurrent.locks.Condition) Test(org.testng.annotations.Test)

Example 23 with Condition

use of java.util.concurrent.locks.Condition in project caffeine by ben-manes.

the class NonReentrantLockTest method condition.

@Test(dataProvider = "lock")
@SuppressWarnings("WaitNotInLoop")
public void condition(NonReentrantLock lock) {
    Condition condition = lock.newCondition();
    AtomicBoolean ready = new AtomicBoolean();
    Thread thread = new Thread(() -> {
        lock.lock();
        ready.set(true);
        condition.awaitUninterruptibly();
    });
    thread.start();
    Awaits.await().untilTrue(ready);
    lock.lock();
    assertThat(lock.hasWaiters(condition), is(true));
    assertThat(lock.getWaitQueueLength(condition), is(1));
    assertThat(lock.getWaitingThreads(condition), contains(thread));
    condition.signal();
    lock.unlock();
}
Also used : Condition(java.util.concurrent.locks.Condition) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Test(org.testng.annotations.Test)

Example 24 with Condition

use of java.util.concurrent.locks.Condition in project kafka by apache.

the class BufferPool method allocate.

/**
     * Allocate a buffer of the given size. This method blocks if there is not enough memory and the buffer pool
     * is configured with blocking mode.
     * 
     * @param size The buffer size to allocate in bytes
     * @param maxTimeToBlockMs The maximum time in milliseconds to block for buffer memory to be available
     * @return The buffer
     * @throws InterruptedException If the thread is interrupted while blocked
     * @throws IllegalArgumentException if size is larger than the total memory controlled by the pool (and hence we would block
     *         forever)
     */
public ByteBuffer allocate(int size, long maxTimeToBlockMs) throws InterruptedException {
    if (size > this.totalMemory)
        throw new IllegalArgumentException("Attempt to allocate " + size + " bytes, but there is a hard limit of " + this.totalMemory + " on memory allocations.");
    this.lock.lock();
    try {
        // check if we have a free buffer of the right size pooled
        if (size == poolableSize && !this.free.isEmpty())
            return this.free.pollFirst();
        // now check if the request is immediately satisfiable with the
        // memory on hand or if we need to block
        int freeListSize = freeSize() * this.poolableSize;
        if (this.availableMemory + freeListSize >= size) {
            // we have enough unallocated or pooled memory to immediately
            // satisfy the request
            freeUp(size);
            this.availableMemory -= size;
            lock.unlock();
            return allocateByteBuffer(size);
        } else {
            // we are out of memory and will have to block
            int accumulated = 0;
            ByteBuffer buffer = null;
            Condition moreMemory = this.lock.newCondition();
            long remainingTimeToBlockNs = TimeUnit.MILLISECONDS.toNanos(maxTimeToBlockMs);
            this.waiters.addLast(moreMemory);
            // enough memory to allocate one
            while (accumulated < size) {
                long startWaitNs = time.nanoseconds();
                long timeNs;
                boolean waitingTimeElapsed;
                try {
                    waitingTimeElapsed = !moreMemory.await(remainingTimeToBlockNs, TimeUnit.NANOSECONDS);
                } catch (InterruptedException e) {
                    this.waiters.remove(moreMemory);
                    throw e;
                } finally {
                    long endWaitNs = time.nanoseconds();
                    timeNs = Math.max(0L, endWaitNs - startWaitNs);
                    this.waitTime.record(timeNs, time.milliseconds());
                }
                if (waitingTimeElapsed) {
                    this.waiters.remove(moreMemory);
                    throw new TimeoutException("Failed to allocate memory within the configured max blocking time " + maxTimeToBlockMs + " ms.");
                }
                remainingTimeToBlockNs -= timeNs;
                // otherwise allocate memory
                if (accumulated == 0 && size == this.poolableSize && !this.free.isEmpty()) {
                    // just grab a buffer from the free list
                    buffer = this.free.pollFirst();
                    accumulated = size;
                } else {
                    // we'll need to allocate memory, but we may only get
                    // part of what we need on this iteration
                    freeUp(size - accumulated);
                    int got = (int) Math.min(size - accumulated, this.availableMemory);
                    this.availableMemory -= got;
                    accumulated += got;
                }
            }
            // remove the condition for this thread to let the next thread
            // in line start getting memory
            Condition removed = this.waiters.removeFirst();
            if (removed != moreMemory)
                throw new IllegalStateException("Wrong condition: this shouldn't happen.");
            // over for them
            if (this.availableMemory > 0 || !this.free.isEmpty()) {
                if (!this.waiters.isEmpty())
                    this.waiters.peekFirst().signal();
            }
            // unlock and return the buffer
            lock.unlock();
            if (buffer == null)
                return allocateByteBuffer(size);
            else
                return buffer;
        }
    } finally {
        if (lock.isHeldByCurrentThread())
            lock.unlock();
    }
}
Also used : Condition(java.util.concurrent.locks.Condition) ByteBuffer(java.nio.ByteBuffer) TimeoutException(org.apache.kafka.common.errors.TimeoutException)

Example 25 with Condition

use of java.util.concurrent.locks.Condition in project kafka by apache.

the class BufferPool method deallocate.

/**
     * Return buffers to the pool. If they are of the poolable size add them to the free list, otherwise just mark the
     * memory as free.
     * 
     * @param buffer The buffer to return
     * @param size The size of the buffer to mark as deallocated, note that this may be smaller than buffer.capacity
     *             since the buffer may re-allocate itself during in-place compression
     */
public void deallocate(ByteBuffer buffer, int size) {
    lock.lock();
    try {
        if (size == this.poolableSize && size == buffer.capacity()) {
            buffer.clear();
            this.free.add(buffer);
        } else {
            this.availableMemory += size;
        }
        Condition moreMem = this.waiters.peekFirst();
        if (moreMem != null)
            moreMem.signal();
    } finally {
        lock.unlock();
    }
}
Also used : Condition(java.util.concurrent.locks.Condition)

Aggregations

Condition (java.util.concurrent.locks.Condition)45 ReentrantLock (java.util.concurrent.locks.ReentrantLock)30 Lock (java.util.concurrent.locks.Lock)18 Test (org.junit.Test)14 ArrayList (java.util.ArrayList)6 HttpResponse (org.apache.http.HttpResponse)6 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 AtomicReference (java.util.concurrent.atomic.AtomicReference)4 ByteBuffer (java.nio.ByteBuffer)3 User (com.lonepulse.robozombie.model.User)2 InvocationException (com.lonepulse.robozombie.proxy.InvocationException)2 IOException (java.io.IOException)2 Collection (java.util.Collection)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2 Map (java.util.Map)2 Executor (java.util.concurrent.Executor)2 Test (org.testng.annotations.Test)2