tag:blogger.com,1999:blog-4110180.post5959616301150738298..comments2023-06-20T05:31:24.545-07:00Comments on Tapestry Central: Synchronized Considered HarmfulAnonymoushttp://www.blogger.com/profile/04486596490758986709noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-4110180.post-83225156595629636022012-06-11T11:53:48.477-07:002012-06-11T11:53:48.477-07:00A note: I chose the getMessages() example for simp...A note: I chose the getMessages() example for simplicity; further research has shown that it is safe to dispence with both synchronized and the locks for this particular field: It is write-once, and if multiple threads invoke elementResources.getMessages(), they will receive the same value: it is cached.<br /><br />However, many of the other methods of InternalComponentResourcesImpl require the full-blown read/write lock technique for correctness and scalability.Anonymoushttps://www.blogger.com/profile/04486596490758986709noreply@blogger.comtag:blogger.com,1999:blog-4110180.post-71816452717567635272012-06-07T15:17:52.200-07:002012-06-07T15:17:52.200-07:00Just pulled out Goetz's book. @Unknown: see pa...Just pulled out Goetz's book. @Unknown: see page 349 (your example is marked "don't do this"). This is DCL ("double checked locking"), broken before 1.5, works in 1.5+ only if the field (messages) is volatile.Anonymoushttps://www.blogger.com/profile/04486596490758986709noreply@blogger.comtag:blogger.com,1999:blog-4110180.post-51599519356717910412012-06-07T09:55:40.097-07:002012-06-07T09:55:40.097-07:00@Jed
LazyReference looks cool; you should do a fo...@Jed<br /><br />LazyReference looks cool; you should do a follow on blog post about it. In my circumstance, one of the issues is to reduce the number of objects in the system: in some of my client's larger applications, they have dozens (sometimes hundreds) of pages, each with thousands of components, and multiple localization. Each component consists of a number of objects, and having excess objects can, really, truly, add up.<br /><br />I should do some testing about volatile (with a single write lock) vs. the technique discussed in the main blog posting. I suspect volatile approach would be faster for lazy initialization cases (but not for cases where the field changes value more than once).Anonymoushttps://www.blogger.com/profile/04486596490758986709noreply@blogger.comtag:blogger.com,1999:blog-4110180.post-71388923035691970362012-06-07T09:51:18.353-07:002012-06-07T09:51:18.353-07:00@Unknown
That's classic double check locked c...@Unknown<br /><br />That's classic double check locked code that was popularized, incorrectly, around 2001. It does not ensure that all threads see a consistent view of the messages field.Anonymoushttps://www.blogger.com/profile/04486596490758986709noreply@blogger.comtag:blogger.com,1999:blog-4110180.post-46898619371778496642012-06-07T07:50:29.620-07:002012-06-07T07:50:29.620-07:00Why not use a double check like this:
public Map ...Why not use a double check like this:<br /><br />public Map getMessages()<br />if(messages == null){<br />synchronized(mutex){<br />if(messages == null){<br />//load messages here<br />}<br />}<br />}<br />return messages;<br />}Unknownhttps://www.blogger.com/profile/15242624567173250565noreply@blogger.comtag:blogger.com,1999:blog-4110180.post-54153749320890163852012-06-06T21:48:54.337-07:002012-06-06T21:48:54.337-07:00Yeah, lazy initialisation is painful and easy to g...Yeah, lazy initialisation is painful and easy to get wrong. I got so sick of seeing people get it wrong in various ways I wrote a utility class that encapsulated the right way to do it along with the fastest access (volatile semantics basically) possible.<br /><br />Declaration is basically:<br /><br /> private final LazyReference = new LazyReference() {<br /> protected abstract Message create() {<br /> return elementResources.getMessages(componentModel);<br /> }<br /> };<br /><br />and usage is<br /><br /> Messages m = messages.get();<br /><br />some docs: https://labs.atlassian.com/wiki/display/CONCURRENT/LazyReference+and+ResettableLazyReference<br />src is now on bitbucket: https://bitbucket.org/atlassian/atlassian-util-concurrent/<br />for instance: https://bitbucket.org/atlassian/atlassian-util-concurrent/src/492a00b90972/src/main/java/com/atlassian/util/concurrent/LazyReference.java<br /><br />There is also a form of memoizing Supplier that supports timed-out caching as well:<br />https://bitbucket.org/atlassian/atlassian-util-concurrent/src/492a00b90972/src/main/java/com/atlassian/util/concurrent/Lazy.javajedhttps://www.blogger.com/profile/03788339539345176707noreply@blogger.com