use of java.util.concurrent.locks.Condition in project apex-core by apache.
the class AbstractReservoirTest method testSpscBlockingQueuePerformance.
@Test
@Ignore
public void testSpscBlockingQueuePerformance() {
final SpscArrayQueue<Object> spscArrayQueue = new SpscArrayQueue<>(CAPACITY);
final ReentrantLock lock = new ReentrantLock();
final Condition notFull = lock.newCondition();
final long start = System.currentTimeMillis();
final Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
int sleepMillis;
for (int i = 0; i < COUNT; i++) {
sleepMillis = 0;
while (spscArrayQueue.poll() == null) {
sleep(sleepMillis);
sleepMillis = Math.min(10, sleepMillis + 1);
}
lock.lock();
notFull.signal();
lock.unlock();
}
} catch (InterruptedException e) {
logger.error("Interrupted", e);
throw new RuntimeException(e);
}
}
});
t.start();
final Object o = new Byte[128];
try {
for (int i = 0; i < COUNT; i++) {
if (!spscArrayQueue.offer(o)) {
lock.lockInterruptibly();
while (!spscArrayQueue.offer(o)) {
notFull.await();
}
lock.unlock();
}
}
t.join();
} catch (InterruptedException e) {
logger.error("Interrupted", e);
throw new RuntimeException(e);
}
logger.debug("Time {}", System.currentTimeMillis() - start);
}
use of java.util.concurrent.locks.Condition in project ignite by apache.
the class GridTaskCommandHandler method requestTaskResult.
/**
* @param resHolderId Result holder.
* @param taskId Task ID.
* @return Response from task holder.
*/
private IgniteBiTuple<String, GridTaskResultResponse> requestTaskResult(final UUID resHolderId, IgniteUuid taskId) {
ClusterNode taskNode = ctx.discovery().node(resHolderId);
if (taskNode == null)
return F.t("Task result holder has left grid: " + resHolderId, null);
// Tuple: error message-response.
final IgniteBiTuple<String, GridTaskResultResponse> t = new IgniteBiTuple<>();
final Lock lock = new ReentrantLock();
final Condition cond = lock.newCondition();
GridMessageListener msgLsnr = new GridMessageListener() {
@Override
public void onMessage(UUID nodeId, Object msg) {
String err = null;
GridTaskResultResponse res = null;
if (!(msg instanceof GridTaskResultResponse))
err = "Received unexpected message: " + msg;
else if (!nodeId.equals(resHolderId))
err = "Received task result response from unexpected node [resHolderId=" + resHolderId + ", nodeId=" + nodeId + ']';
else
// Sender and message type are fine.
res = (GridTaskResultResponse) msg;
try {
res.result(U.unmarshal(ctx, res.resultBytes(), U.resolveClassLoader(ctx.config())));
} catch (IgniteCheckedException e) {
U.error(log, "Failed to unmarshal task result: " + res, e);
}
lock.lock();
try {
if (t.isEmpty()) {
t.set(err, res);
cond.signalAll();
}
} finally {
lock.unlock();
}
}
};
GridLocalEventListener discoLsnr = new GridLocalEventListener() {
@Override
public void onEvent(Event evt) {
assert evt instanceof DiscoveryEvent && (evt.type() == EVT_NODE_FAILED || evt.type() == EVT_NODE_LEFT) : "Unexpected event: " + evt;
DiscoveryEvent discoEvt = (DiscoveryEvent) evt;
if (resHolderId.equals(discoEvt.eventNode().id())) {
lock.lock();
try {
if (t.isEmpty()) {
t.set("Node that originated task execution has left grid: " + resHolderId, null);
cond.signalAll();
}
} finally {
lock.unlock();
}
}
}
};
// 1. Create unique topic name and register listener.
Object topic = TOPIC_REST.topic("task-result", topicIdGen.getAndIncrement());
try {
ctx.io().addMessageListener(topic, msgLsnr);
// 2. Send message.
try {
byte[] topicBytes = U.marshal(ctx, topic);
ctx.io().sendToGridTopic(taskNode, TOPIC_REST, new GridTaskResultRequest(taskId, topic, topicBytes), SYSTEM_POOL);
} catch (IgniteCheckedException e) {
String errMsg = "Failed to send task result request [resHolderId=" + resHolderId + ", err=" + e.getMessage() + ']';
if (log.isDebugEnabled())
log.debug(errMsg);
return F.t(errMsg, null);
}
// 3. Listen to discovery events.
ctx.event().addLocalEventListener(discoLsnr, EVT_NODE_FAILED, EVT_NODE_LEFT);
// 4. Check whether node has left before disco listener has been installed.
taskNode = ctx.discovery().node(resHolderId);
if (taskNode == null)
return F.t("Task result holder has left grid: " + resHolderId, null);
// 5. Wait for result.
lock.lock();
try {
long netTimeout = ctx.config().getNetworkTimeout();
if (t.isEmpty())
cond.await(netTimeout, MILLISECONDS);
if (t.isEmpty())
t.set1("Timed out waiting for task result (consider increasing 'networkTimeout' " + "configuration property) [resHolderId=" + resHolderId + ", netTimeout=" + netTimeout + ']');
// Return result
return t;
} catch (InterruptedException ignored) {
Thread.currentThread().interrupt();
return F.t("Interrupted while waiting for task result.", null);
} finally {
lock.unlock();
}
} finally {
ctx.io().removeMessageListener(topic, msgLsnr);
ctx.event().removeLocalEventListener(discoLsnr);
}
}
use of java.util.concurrent.locks.Condition in project ignite by apache.
the class OffheapReadWriteLock method waitAcquireReadLock.
/**
* Acquires read lock in waiting loop.
*
* @param lock Lock address.
* @param lockIdx Lock index.
* @param tag Validation tag.
* @return {@code True} if lock was acquired, {@code false} if tag validation failed.
*/
private boolean waitAcquireReadLock(long lock, int lockIdx, int tag) {
ReentrantLock lockObj = locks[lockIdx];
Condition waitCond = readConditions[lockIdx];
assert lockObj.isHeldByCurrentThread();
boolean interrupted = false;
try {
while (true) {
try {
long state = GridUnsafe.getLongVolatile(null, lock);
if (!checkTag(state, tag)) {
// We cannot lock with this tag, release waiter.
long updated = updateState(state, 0, -1, 0);
if (GridUnsafe.compareAndSwapLong(null, lock, state, updated)) {
int writeWaitCnt = writersWaitCount(updated);
int readWaitCnt = readersWaitCount(updated);
signalNextWaiter(writeWaitCnt, readWaitCnt, lockIdx);
return false;
}
} else if (canReadLock(state)) {
long updated = updateState(state, 1, -1, 0);
if (GridUnsafe.compareAndSwapLong(null, lock, state, updated))
return true;
} else
waitCond.await();
} catch (InterruptedException ignore) {
interrupted = true;
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
use of java.util.concurrent.locks.Condition in project CorfuDB by CorfuDB.
the class MapsAsMQsTest method useMapsAsMQs.
/**
* This test verifies commit atomicity against concurrent -read- activity,
* which constantly causes rollbacks and optimistic-rollbacks.
*
* @throws Exception
*/
@Test
public void useMapsAsMQs() throws Exception {
String mapName1 = "testMapA";
Map<Long, Long> testMap1 = instantiateCorfuObject(SMRMap.class, mapName1);
final int nThreads = 4;
CountDownLatch barrier = new CountDownLatch(nThreads - 1);
ReentrantLock lock = new ReentrantLock();
Condition c1 = lock.newCondition();
Condition c2 = lock.newCondition();
// 1st thread: producer of new "trigger" values
scheduleConcurrently(t -> {
barrier.await();
log.debug("all started");
for (int i = 0; i < numIterations; i++) {
try {
lock.lock();
log.debug("- sending 1st trigger " + i);
testMap1.put(1L, (long) i);
c2.await();
log.debug("- sending 2nd trigger " + i);
} finally {
}
}
});
// 2nd thread: monitor map and wait for "trigger" values to show up, produce 1st signal
scheduleConcurrently(t -> {
barrier.countDown();
int busyDelay = 1;
for (int i = 0; i < numIterations; i++) {
while (testMap1.get(1L) == null || testMap1.get(1L) != (long) i) {
log.debug("- wait for 1st trigger " + i);
Thread.sleep(busyDelay);
}
log.debug("- received 1st trigger " + i);
try {
lock.lock();
c1.signal();
} finally {
lock.unlock();
}
}
});
// 3rd thread: monitor 1st producer condition and produce a second "trigger"
scheduleConcurrently(t -> {
barrier.countDown();
for (int i = 0; i < numIterations; i++) {
try {
TXBegin();
lock.lock();
c1.await();
log.debug("- received 1st condition " + i);
log.debug("- sending 2nd trigger " + i);
testMap1.put(2L, (long) i);
TXEnd();
} finally {
lock.unlock();
}
}
});
// 4th thread: monitor map and wait for 2nd "trigger" values to show up, produce second signal
scheduleConcurrently(t -> {
barrier.countDown();
int busyDelay = 1;
for (int i = 0; i < numIterations; i++) {
while (testMap1.get(2L) == null || testMap1.get(2L) != (long) i) Thread.sleep(busyDelay);
log.debug("- received 2nd trigger " + i);
try {
lock.lock();
log.debug("- sending 2nd signal " + i);
c2.signal();
} finally {
lock.unlock();
}
}
});
executeScheduled(nThreads, PARAMETERS.TIMEOUT_LONG);
}
use of java.util.concurrent.locks.Condition in project LiveLessons by douglascraigschmidt.
the class PlayPingPong method makePingPongThreads.
/**
* Factory method that creates the designated instances of the
* PingPongThread subclass based on the @code syncMechanism
* parameter.
*/
private void makePingPongThreads(String syncMechanism, PingPongThread[] pingPongThreads) {
if (syncMechanism.equals("SEMA")) {
// Create the Java Semaphores that ensure threads print
// "ping" and "pong" in the correct alternating order.
Semaphore pingSema = // Starts out unlocked.
new Semaphore(1);
Semaphore pongSema = new Semaphore(0);
pingPongThreads[PING_THREAD] = new PingPongThreadSema("ping", pingSema, pongSema, mMaxIterations);
pingPongThreads[PONG_THREAD] = new PingPongThreadSema("pong", pongSema, pingSema, mMaxIterations);
} else if (syncMechanism.equals("MONOBJ")) {
// Create the BinarySemaphores (implemented as Java
// build-in monitor objects) that ensure threads print
// "ping" and "pong" in the correct alternating order.
PingPongThreadMonObj.BinarySemaphore pingSema = // Start out unlocked.
new PingPongThreadMonObj.BinarySemaphore(true);
PingPongThreadMonObj.BinarySemaphore pongSema = new PingPongThreadMonObj.BinarySemaphore(false);
pingPongThreads[PING_THREAD] = new PingPongThreadMonObj("ping", pingSema, pongSema, mMaxIterations);
pingPongThreads[PONG_THREAD] = new PingPongThreadMonObj("pong", pongSema, pingSema, mMaxIterations);
} else if (syncMechanism.equals("COND")) {
// Create the ReentrantLock and Conditions that ensure
// threads print "ping" and "pong" in the correct
// alternating order.
ReentrantLock lock = new ReentrantLock();
Condition pingCond = lock.newCondition();
Condition pongCond = lock.newCondition();
PingPongThreadCond pingThread = new PingPongThreadCond("ping", lock, pingCond, pongCond, true, mMaxIterations);
PingPongThreadCond pongThread = new PingPongThreadCond("pong", lock, pongCond, pingCond, false, mMaxIterations);
// Exchange Thread IDs.
pingThread.setOtherThreadId(pongThread.getId());
pongThread.setOtherThreadId(pingThread.getId());
pingPongThreads[PING_THREAD] = pingThread;
pingPongThreads[PONG_THREAD] = pongThread;
} else if (syncMechanism.equals("QUEUE")) {
// Create the LinkedBlockingQueues that ensure threads
// print "ping" and "pong" in the correct alternating
// order.
LinkedBlockingQueue<Object> pingQueue = new LinkedBlockingQueue<Object>();
LinkedBlockingQueue<Object> pongQueue = new LinkedBlockingQueue<Object>();
Object pingPongBall = new Object();
try {
// Initialize this implementation by putting an object
// onto the "pong" queue.
pongQueue.put(pingPongBall);
} catch (InterruptedException e) {
throw new RuntimeException();
}
pingPongThreads[PING_THREAD] = new PingPongThreadBlockingQueue("ping", pingQueue, pongQueue, mMaxIterations);
pingPongThreads[PONG_THREAD] = new PingPongThreadBlockingQueue("pong", pongQueue, pingQueue, mMaxIterations);
}
}
Aggregations