protected void flush(final Address new_coord) throws InterruptedException { // wait until all threads currently sending messages have returned (new threads after // flushing=true) will block // flushing is set to true in startFlusher() while (flushing && running) { if (in_flight_sends.get() == 0) break; Thread.sleep(100); } send_lock.lockInterruptibly(); try { if (log.isTraceEnabled()) log.trace(local_addr + ": coord changed from " + coord + " to " + new_coord); coord = new_coord; is_coord = Objects.equals(local_addr, coord); flushMessagesInForwardTable(); } finally { if (log.isTraceEnabled()) log.trace(local_addr + ": flushing completed"); flushing = false; ack_mode = true; // go to ack-mode after flushing num_acks = 0; send_cond.signalAll(); send_lock.unlock(); } }
/** * Gets connection listener instance associated with transaction. This method is package protected * beacause it is intended only for test case use. Please don't use it in your production code. * * @param trackByTransaction transaction instance * @param mcp the managed connection pool associated with the desired connection listener * @return connection listener instance * @throws ResourceException Thrown if an error occurs */ ConnectionListener getTransactionOldConnection( Transaction trackByTransaction, ManagedConnectionPool mcp) throws ResourceException { TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry(); Lock lock = getLock(); try { lock.lockInterruptibly(); } catch (InterruptedException ie) { Thread.interrupted(); throw new ResourceException(bundle.unableObtainLock(), ie); } try { // Already got one ConnectionListener cl = (ConnectionListener) tsr.getResource(mcp); if (cl != null) { if (trace) log.tracef("Previous connection tracked by transaction=%s tx=%s", cl, trackByTransaction); return cl; } return null; } finally { lock.unlock(); } }
public void f() { try { lock.lockInterruptibly(); } catch (InterruptedException e) { System.err.println("ReentrantLockBlockTask is interrupted"); } System.out.println("Exit from ReentrantLockBlockTask"); }
public void f() { try { lock.lockInterruptibly(); System.out.println("lock acquired in f()"); } catch (InterruptedException e) { System.out.println("Interrupted from lock acquisition in f()"); } }
@Override protected void handleMessageInternal(Message<?> message) throws Exception { Object correlationKey = correlationStrategy.getCorrelationKey(message); Assert.state( correlationKey != null, "Null correlation not allowed. Maybe the CorrelationStrategy is failing?"); if (logger.isDebugEnabled()) { logger.debug("Handling message with correlationKey [" + correlationKey + "]: " + message); } UUID groupIdUuid = UUIDConverter.getUUID(correlationKey); Lock lock = this.lockRegistry.obtain(groupIdUuid.toString()); lock.lockInterruptibly(); try { ScheduledFuture<?> scheduledFuture = this.expireGroupScheduledFutures.remove(groupIdUuid); if (scheduledFuture != null) { boolean canceled = scheduledFuture.cancel(true); if (canceled && logger.isDebugEnabled()) { logger.debug( "Cancel 'forceComplete' scheduling for MessageGroup with Correlation Key [ " + correlationKey + "]."); } } MessageGroup messageGroup = messageStore.getMessageGroup(correlationKey); if (this.sequenceAware) { messageGroup = new SequenceAwareMessageGroup(messageGroup); } if (!messageGroup.isComplete() && messageGroup.canAdd(message)) { if (logger.isTraceEnabled()) { logger.trace("Adding message to group [ " + messageGroup + "]"); } messageGroup = this.store(correlationKey, message); if (releaseStrategy.canRelease(messageGroup)) { Collection<Message<?>> completedMessages = null; try { completedMessages = this.completeGroup(message, correlationKey, messageGroup); } finally { // Always clean up even if there was an exception // processing messages this.afterRelease(messageGroup, completedMessages); } } else { scheduleGroupToForceComplete(messageGroup); } } else { discardMessage(message); } } finally { lock.unlock(); } }
private void scan() throws OperationFailedException { try { scanLock.lockInterruptibly(); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); return; } try { if (scanEnabled) { // confirm the scan is still wanted log.tracef( "Scanning directory %s for deployment content changes", deploymentDir.getAbsolutePath()); final List<ModelNode> updates = new ArrayList<ModelNode>(); Map<String, File> foundDeployed = new HashMap<String, File>(); Set<String> newlyAdded = new HashSet<String>(); Set<String> registeredDeployments = getDeploymentNames(); scanDirectory(deploymentDir, updates, foundDeployed, newlyAdded, registeredDeployments); // Add remove actions to the plan for anything we count as // deployed that we didn't find on the scan Set<String> toRemove = new HashSet<String>(deployed); toRemove.removeAll(foundDeployed.keySet()); toRemove.removeAll(newlyAdded); // in case user removed the marker and added replacement for (String missing : toRemove) { updates.add(getUndeployOperation(missing)); updates.add(getRemoveOperation(missing)); } if (updates.size() > 0) { if (log.isDebugEnabled()) { for (ModelNode update : updates) { log.debugf("Deployment scan of [%s] found update action [%s]", deploymentDir, update); } } Operation composite = getCompositeUpdate(updates); ModelNode results = serverController.execute(composite); // System.out.println(composite); // System.out.println(results); // FIXME deal with result } // Throw away any found marker files that we didn't already know about Set<String> validFinds = cleanSpuriousMarkerFiles(foundDeployed); validFinds.addAll(newlyAdded); this.deployed = validFinds; log.tracef("Scan complete"); } } finally { scanLock.unlock(); } }
/** * Gets new connection listener if necessary instance with transaction. This method is package * protected beacause it is intended only for test case use. Please don't use it in your * production code. * * @param trackByTransaction transaction instance * @param mcp pool instance * @param subject subject instance * @param cri connection request info * @return connection listener instance * @throws ResourceException ResourceException */ ConnectionListener getTransactionNewConnection( Transaction trackByTransaction, ManagedConnectionPool mcp, Subject subject, ConnectionRequestInfo cri) throws ResourceException { // Need a new one for this transaction // This must be done outside the tx local lock, otherwise // the tx timeout won't work and get connection can do a lot of other work // with many opportunities for deadlocks. // Instead we do a double check after we got the transaction to see // whether another thread beat us to the punch. ConnectionListener cl = mcp.getConnection(subject, cri); if (trace) log.tracef( "Got connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction); TransactionSynchronizationRegistry tsr = getTransactionSynchronizationRegistry(); Lock lock = getLock(); try { lock.lockInterruptibly(); } catch (InterruptedException ie) { Thread.interrupted(); throw new ResourceException(bundle.unableObtainLock(), ie); } try { // Check we weren't racing with another transaction ConnectionListener other = (ConnectionListener) tsr.getResource(mcp); if (other != null) { mcp.returnConnection(cl, false); if (trace) log.tracef( "Another thread already got a connection tracked by transaction=%s tx=%s", other, trackByTransaction); cl = other; } // This is the connection for this transaction cl.setTrackByTx(true); tsr.putResource(mcp, cl); if (trace) log.tracef( "Using connection from pool tracked by transaction=%s tx=%s", cl, trackByTransaction); return cl; } finally { lock.unlock(); } }
public void insert(Thread thread) throws InterruptedException { lock.lockInterruptibly(); // 注意,如果需要正确中断等待锁的线程,必须将获取锁放在外面,然后将InterruptedException抛出 try { System.out.println(thread.getName() + "得到了锁"); long startTime = System.currentTimeMillis(); for (; ; ) { if (System.currentTimeMillis() - startTime >= Integer.MAX_VALUE) break; // 插入数据 } } finally { System.out.println(Thread.currentThread().getName() + "执行finally"); lock.unlock(); System.out.println(thread.getName() + "释放了锁"); } }
protected void forceComplete(MessageGroup group) { Object correlationKey = group.getGroupId(); // UUIDConverter is no-op if already converted Lock lock = this.lockRegistry.obtain(UUIDConverter.getUUID(correlationKey).toString()); boolean removeGroup = true; try { lock.lockInterruptibly(); try { ScheduledFuture<?> scheduledFuture = this.expireGroupScheduledFutures.remove(UUIDConverter.getUUID(correlationKey)); if (scheduledFuture != null) { boolean canceled = scheduledFuture.cancel(false); if (canceled && logger.isDebugEnabled()) { logger.debug("Cancel 'forceComplete' scheduling for MessageGroup [ " + group + "]."); } } MessageGroup groupNow = group; /* * If the group argument is not already complete, * re-fetch it because it might have changed while we were waiting on * its lock. If the last modified timestamp changed, defer the completion * because the selection condition may have changed such that the group * would no longer be eligible. If the timestamp changed, it's a completely new * group and should not be reaped on this cycle. * * If the group argument is already complete, do not re-fetch. * Note: not all message stores provide a direct reference to its internal * group so the initial 'isComplete()` will only return true for those stores if * the group was already complete at the time of its selection as a candidate. * * If the group is marked complete, only consider it * for reaping if it's empty (and both timestamps are unaltered). */ if (!group.isComplete()) { groupNow = this.messageStore.getMessageGroup(correlationKey); } long lastModifiedNow = groupNow.getLastModified(); int groupSize = groupNow.size(); if ((!groupNow.isComplete() || groupSize == 0) && group.getLastModified() == lastModifiedNow && group.getTimestamp() == groupNow.getTimestamp()) { if (groupSize > 0) { if (releaseStrategy.canRelease(groupNow)) { completeGroup(correlationKey, groupNow); } else { expireGroup(correlationKey, groupNow); } if (!this.expireGroupsUponTimeout) { afterRelease(groupNow, groupNow.getMessages(), true); removeGroup = false; } } else { /* * By default empty groups are removed on the same schedule as non-empty * groups. A longer timeout for empty groups can be enabled by * setting minimumTimeoutForEmptyGroups. */ removeGroup = lastModifiedNow <= (System.currentTimeMillis() - this.minimumTimeoutForEmptyGroups); if (removeGroup && logger.isDebugEnabled()) { logger.debug("Removing empty group: " + correlationKey); } } } else { removeGroup = false; if (logger.isDebugEnabled()) { logger.debug( "Group expiry candidate (" + correlationKey + ") has changed - it may be reconsidered for a future expiration"); } } } catch (MessageDeliveryException e) { removeGroup = false; if (logger.isDebugEnabled()) { logger.debug( "Group expiry candidate (" + correlationKey + ") has been affected by MessageDeliveryException - " + "it may be reconsidered for a future expiration one more time"); } throw e; } finally { try { if (removeGroup) { this.remove(group); } } finally { lock.unlock(); } } } catch (InterruptedException ie) { Thread.currentThread().interrupt(); logger.debug("Thread was interrupted while trying to obtain lock"); } }
@Override public void lockInterruptibly() throws InterruptedException { wrapped.lockInterruptibly(); }
/** * Acquire the given lock interruptibly, holding a reference to it for cleanup on thread * termination. * * @param lock the lock to acquire, released on thread termination * @throws InterruptedException if the lock acquisition is interrupted */ public void lockInterruptibly(Lock lock) throws InterruptedException { assert Thread.currentThread() == getNativeThread(); lock.lockInterruptibly(); heldLocks.add(lock); }
/** This method isn't private solely to allow a unit test in the same package to call it */ void scan() { try { scanLock.lockInterruptibly(); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); return; } try { if (scanEnabled) { // confirm the scan is still wanted log.tracef( "Scanning directory %s for deployment content changes", deploymentDir.getAbsolutePath()); List<ScannerTask> scannerTasks = new ArrayList<ScannerTask>(); final Set<String> registeredDeployments = getDeploymentNames(); final Set<String> toRemove = new HashSet<String>(deployed.keySet()); scanDirectory(deploymentDir, scannerTasks, registeredDeployments, toRemove); // Add remove actions to the plan for anything we count as // deployed that we didn't find on the scan for (String missing : toRemove) { // TODO -- minor -- this assumes the deployment was in the root deploymentDir, // not a child dir, and therefore puts the '.undeploying' file there File parent = deploymentDir; scannerTasks.add(new UndeployTask(missing, parent)); } if (scannerTasks.size() > 0) { List<ModelNode> updates = new ArrayList<ModelNode>(scannerTasks.size()); for (ScannerTask task : scannerTasks) { final ModelNode update = task.getUpdate(); if (log.isDebugEnabled()) { log.debugf("Deployment scan of [%s] found update action [%s]", deploymentDir, update); } updates.add(update); } while (!updates.isEmpty()) { ModelNode composite = getCompositeUpdate(updates); final ModelNode results = serverController.execute(OperationBuilder.Factory.create(composite).build()); final List<Property> resultList = results.get(RESULT).asPropertyList(); final List<ModelNode> toRetry = new ArrayList<ModelNode>(); final List<ScannerTask> retryTasks = new ArrayList<ScannerTask>(); for (int i = 0; i < resultList.size(); i++) { final ModelNode result = resultList.get(i).getValue(); final ScannerTask task = scannerTasks.get(i); final ModelNode outcome = result.get(OUTCOME); if (outcome.isDefined() && SUCCESS.equals(outcome.asString())) { task.handleSuccessResult(); } else if (outcome.isDefined() && CANCELLED.equals(outcome.asString())) { toRetry.add(updates.get(i)); retryTasks.add(task); } else { task.handleFailureResult(result); } } updates = toRetry; scannerTasks = retryTasks; } } log.tracef("Scan complete"); } } finally { scanLock.unlock(); } }