<style>
/* Changing the layout to use less space for mobiles */
@media screen and (max-device-width: 480px), screen and (-webkit-min-device-pixel-ratio: 2) {
#email-body { min-width: 30em !important; }
#email-page { padding: 8px !important; }
#email-banner { padding: 8px 8px 0 8px !important; }
#email-avatar { margin: 1px 8px 8px 0 !important; padding: 0 !important; }
#email-fields { padding: 0 8px 8px 8px !important; }
#email-gutter { width: 0 !important; }
}
</style>
<div id="email-body">
<table id="email-wrap" align="center" border="0" cellpadding="0" cellspacing="0" style="background-color:#f0f0f0;color:#000000;width:100%;">
<tr valign="top">
<td id="email-page" style="padding:16px !important;">
<table align="center" border="0" cellpadding="0" cellspacing="0" style="background-color:#ffffff;border:1px solid #bbbbbb;color:#000000;width:100%;">
<tr valign="top">
<td bgcolor="#3b4d64" style="background-color:#3b4d64;color:#ffffff;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;line-height:1;"><img src="https://issues.jboss.org/s/en_US-g3yjjf/733/58/_/jira-logo-scaled.png" alt="" style="vertical-align:top;" /></td>
</tr><tr valign="top">
<td id="email-banner" style="padding:32px 32px 0 32px;">
<table align="left" border="0" cellpadding="0" cellspacing="0" width="100%" style="width:100%;">
<tr valign="top">
<td style="color:#505050;font-family:Arial,FreeSans,Helvetica,sans-serif;padding:0;">
<img id="email-avatar" src="https://community.jboss.org/people/ahus1/avatar/16.png" alt="" height="48" width="48" border="0" align="left" style="padding:0;margin: 0 16px 16px 0;" />
<div id="email-action" style="padding: 0 0 8px 0;font-size:12px;line-height:18px;">
<a class="user-hover" rel="ahus1" id="email_ahus1" href="https://issues.jboss.org/secure/ViewProfile.jspa?name=ahus1" style="color:#003366;">ahus1</a>
updated <img src="https://issues.jboss.org/images/icons/improvement.gif" height="16" width="16" border="0" align="absmiddle" alt="Patch"> <a style='color:#003366;text-decoration:none;' href='https://issues.jboss.org/browse/JBSEAM-4861'>JBSEAM-4861</a>
</div>
<div id="email-summary" style="font-size:16px;line-height:20px;padding:2px 0 16px 0;">
<a style='color:#003366;text-decoration:none;' href='https://issues.jboss.org/browse/JBSEAM-4861'><strong>Component.java uses application wide factoryLock too often </strong></a>
</div>
</td>
</tr>
</table>
</td>
</tr>
<tr valign="top">
<td id="email-fields" style="padding:0 32px 32px 32px;">
<table border="0" cellpadding="0" cellspacing="0" style="padding:0;text-align:left;width:100%;" width="100%">
<tr valign="top">
<td id="email-gutter" style="width:64px;white-space:nowrap;"></td>
<td>
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Change By:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
<a class="user-hover" rel="ahus1" id="email_ahus1" href="https://issues.jboss.org/secure/ViewProfile.jspa?name=ahus1" style="color:#003366;">ahus1</a>
(01/Jul/12 11:26 AM)
</td>
</tr>
<tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Description:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
<span class="diffcontext">Whenever getInstanceFromFactory() is called and a factory is used, a (application wide) lock is used: factoryLock.<br><br>In my environments the Factory uses expensive calls to the backend to create an object, and during this time no other Factory method is allowed to be called. This is a severe bottleneck in a multiuser environment. <br><br>This lock is important for APPLICATION scoped components, but other components that are i.e. CONVERSATION scoped, Seam already ensures that only one Thread has access to the current conversation. The same should be true for PAGE and EVENT. In this cases no lock should be acquired. UPDATE: Factories that use injection should not be called multithreaded, therefore an updated condition.<br><br>See the follwing code snippet. I also attach a patch. <br><br>I tested the patch for Seam 2.2.2.Final - I would be most happy to have this included in 2.2 and 2.3 branch.<br><br>Br Alexander.<br><br>{code:title=Component.java}<br> ScopeType scopeResult = getOutScope(factoryMethod.getScope(),<br> factoryMethod.getComponent());<br> ScopeType scopeFactory = factoryMethod.getComponent().getScope();<br> boolean lockingNeeded = false;<br> /*<br> * we need this lock in the following cases: (1) the target scope is<br> * accessed by more than one thread (as we don't want to create the same<br> * object by two threads at the same time for the same scope) OR (2) the<br> * factory is accessed by more than one thread and is using interceptors<br> * (as accessing a factory multiple times might mess up interceptors).<br> * This assumes that (1) the scopes CONVERSATION, EVENT and PAGE can't<br> * be accessed by more than one thread anyway due to CONVERSATION being<br> * locked for the current thread anyway, and EVENT and PAGE being only<br> * short-lived anyway. (2) a factory that doesn't use injection can be<br> * accessed multi threaded. See JBSEAM-4669/JBSEAM-2419 for the original<br> * discussion.<br> */<br> if ((scopeResult != ScopeType.CONVERSATION<br> && scopeResult != ScopeType.EVENT && scopeResult != ScopeType.PAGE)<br> || (scopeFactory != ScopeType.CONVERSATION<br> && scopeFactory != ScopeType.EVENT<br> && scopeFactory != ScopeType.PAGE && factoryMethod<br> .getComponent().interceptionEnabled)) {<br> lockingNeeded = true;<br> }<br> if (lockingNeeded) {<br> /*<br> *</span>
<span class="diffaddedchars" style="background-color:#ddfade;"> Only this factory instance can access result scope <br> * CONVERSATION / EVENT / PAGE anyway due to <br> * the locking of the conversation.<br> */<br> if (scopeResult == ScopeType.CONVERSATION<br> || scopeResult == ScopeType.EVENT || scopeResult == ScopeType.PAGE) {<br> synchronized (factory) {<br> return createInstanceFromFactory(name, scope, factoryMethod,<br> factory);<br> }<br> }<br> /*<br> *</span>
<span class="diffcontext"> synchronize all instances of this factory</span>
<span class="diffremovedchars" style="background-color:#ffe7e7;text-decoration:line-through;"> (</span>
<span class="diffaddedchars" style="background-color:#ddfade;"> as</span>
<span class="diffcontext">they might outject to the <br> * same scope</span>
<span class="diffremovedchars" style="background-color:#ffe7e7;text-decoration:line-through;">,</span>
<span class="diffaddedchars" style="background-color:#ddfade;"> (</span>
<span class="diffcontext"> i.e. factory in EVENT scope, outjecting to APPLICATION scope)</span>
<span class="diffremovedchars" style="background-color:#ffe7e7;text-decoration:line-through;">, <br> * let the rest of the world continue</span>
<span class="diffcontext">.<br> */<br></span>
<span class="diffaddedchars" style="background-color:#ddfade;"> else {<br></span>
<span class="diffcontext"> synchronized (factory.getClass()) {<br> return createInstanceFromFactory(name, scope, factoryMethod,<br> factory);<br> }<br> }</span>
<span class="diffaddedchars" style="background-color:#ddfade;"><br> }</span>
<span class="diffcontext"> else {<br> return createInstanceFromFactory(name, scope, factoryMethod, factory);<br> }<br><br>[...]<br><br> private static Object createInstanceFromFactory(String name, ScopeType scope,<br> Init.FactoryMethod factoryMethod, Object factory) {<br> // check whether there has been created an instance by another thread<br> // while waiting for this function's lock<br> if (scope != STATELESS) {<br> Object value = (scope == null) ? Contexts.lookupInStatefulContexts(name)<br> : scope.getContext().get(name);<br> if (value != null) {<br> return value;<br> }<br> }<br> <br> if (factory == null) {<br> return null;<br> } else {<br> Object result = factoryMethod.getComponent().callComponentMethod(factory,<br> factoryMethod.getMethod());<br> return handleFactoryMethodResult(name, factoryMethod.getComponent(),<br> result, factoryMethod.getScope());<br> }<br> }<br><br><br>{code}</span>
</td>
</tr>
<tr valign="top">
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 10px 10px 0;white-space:nowrap;">
<strong style="font-weight:normal;color:#505050;">Forum Reference:</strong>
</td>
<td style="color:#000000;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:12px;padding:0 0 10px 0;width:100%;">
<span class="diffcontext">http://www.seamframework.org/Community/GlobalFactoryLockInComponentjavaPerformanceIssue</span>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td><!-- End #email-page -->
</tr>
<tr valign="top">
<td style="color:#505050;font-family:Arial,FreeSans,Helvetica,sans-serif;font-size:10px;line-height:14px;padding: 0 16px 16px 16px;text-align:center;">
This message is automatically generated by JIRA.<br />
If you think it was sent incorrectly, please contact your <a style='color:#003366;' href='https://issues.jboss.org/secure/ContactAdministrators!default.jspa'>JIRA administrators</a>.<br />
For more information on JIRA, see: <a style='color:#003366;' href='http://www.atlassian.com/software/jira'>http://www.atlassian.com/software/jira</a>
</td>
</tr>
</table><!-- End #email-wrap -->
</div><!-- End #email-body -->