<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: String Interning and Threads</title>
	<atom:link href="http://www.symphonious.net/2004/08/17/string-interning-and-threads/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.symphonious.net/2004/08/17/string-interning-and-threads/</link>
	<description>Living in a state of accord.</description>
	<lastBuildDate>Fri, 12 Mar 2010 07:41:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: 今日連結 (2005-06-10) [JeffHung.Blog]</title>
		<link>http://www.symphonious.net/2004/08/17/string-interning-and-threads/comment-page-1/#comment-53865</link>
		<dc:creator>今日連結 (2005-06-10) [JeffHung.Blog]</dc:creator>
		<pubDate>Tue, 23 Jan 2007 10:02:15 +0000</pubDate>
		<guid isPermaLink="false">http://localhost/wordpress/?p=203#comment-53865</guid>
		<description>[...] 2005 at 9:31 am and filed under Links. Bookmark the permalink. Follow any comments here with the RSS feed for this post.          &#171; 天下體 台灣大哥大行動秘書&#187; [...]</description>
		<content:encoded><![CDATA[<p>[...] 2005 at 9:31 am and filed under Links. Bookmark the permalink. Follow any comments here with the RSS feed for this post.          &laquo; 天下體 台灣大哥大行動秘書&raquo; [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Anonymous</title>
		<link>http://www.symphonious.net/2004/08/17/string-interning-and-threads/comment-page-1/#comment-197</link>
		<dc:creator>Anonymous</dc:creator>
		<pubDate>Thu, 01 Jan 1970 01:00:00 +0000</pubDate>
		<guid isPermaLink="false">http://localhost/wordpress/?p=203#comment-197</guid>
		<description>Hi, Adrian! I&#039;m trying hard not to make myself look too smart (it&#039;s really flattering to hear you give such a high score to my lowly remarks :-).
And please excuse me for a long mail, I tried to say it in words but failed.

I can imagine only three major variations of cache: A, B and C.

My point is that we either

* have synchronization on cache read (A) *

or

* maintain per-thread local cache replicas (B, C) *

variants B and C look quite wasteful in term of memory
(or the don&#039;t, hmm... Adrian?)

And the question is what does intern do?
Perhaps A?

CacheA
{
    Map m_global = new HashMap();

    get( key )
    {
        synchronized( m_global )
        {
            return m_global.get( key );
        }
    }

    put( key, value )
    {
        synchronized( m_global )
        {
            m_global.put( key, value );]
        }
    }
}

CacheB
{
     ThreadLocal m_threadLocal = new ThreadLocal();
     Map m_global = new HashMap();
     
     get( key )
     {
          Map localMap = m_local.get();
          if ( localMap != null )
          {
               Object found = localMap.get( key );
               if ( found != null )
               {
                    return found;
               }
          }
          
          synchronized( m_global )
          {
               Object found = m_global.get( key );
               if ( found != null )
               {
                    if ( localMap == null )
                    {
                         localMap = new HashMap();
                         m_local.put( localMap );
                    }
                    
                    localMap.put( key, found );
               }
               return found;
          }
     }
     
     put( key, value )
     {
          synchronized( m_global )
          {
               m_blobal.put( key, value );
          }
          Map localMap = m_local.get();
          if ( localMap == null )
          {
               localMap = new HashMap();
               m_local.set( localMap );
          }
          localMap.put( key, value );
    }
}

CacheC
{
     ThreadLocal m_threadLocal = new ThreadLocal();
     Map m_global = new HashMap();
     
     get( key )
     {
          Map localMap = m_local.get();
          if ( localMap != null )
          {
               Object found = localMap.get( key );
               if ( found != null )
               {
                    return found;
               }
          }
          
          synchronized( m_global )
          {
               if ( localMap == m_global )
               {
                    return;
               }
               
               m_local.set( m_global );
               return m_global.get( key ):
          }
     }
     
     put( key, value )
     {
          synchronized( m_global )
          {
               m_global = m_global.clone();
               m_global.put( key, value );
               m_local.set( m_global );
          }
    }
}</description>
		<content:encoded><![CDATA[<p>Hi, Adrian! I&#8217;m trying hard not to make myself look too smart (it&#8217;s really flattering to hear you give such a high score to my lowly remarks :-).<br />
And please excuse me for a long mail, I tried to say it in words but failed.</p>
<p>I can imagine only three major variations of cache: A, B and C.</p>
<p>My point is that we either</p>
<p>* have synchronization on cache read (A) *</p>
<p>or</p>
<p>* maintain per-thread local cache replicas (B, C) *</p>
<p>variants B and C look quite wasteful in term of memory<br />
(or the don&#8217;t, hmm&#8230; Adrian?)</p>
<p>And the question is what does intern do?<br />
Perhaps A?</p>
<p>CacheA<br />
{<br />
    Map m_global = new HashMap();</p>
<p>    get( key )<br />
    {<br />
        synchronized( m_global )<br />
        {<br />
            return m_global.get( key );<br />
        }<br />
    }</p>
<p>    put( key, value )<br />
    {<br />
        synchronized( m_global )<br />
        {<br />
            m_global.put( key, value );]<br />
        }<br />
    }<br />
}</p>
<p>CacheB<br />
{<br />
     ThreadLocal m_threadLocal = new ThreadLocal();<br />
     Map m_global = new HashMap();</p>
<p>     get( key )<br />
     {<br />
          Map localMap = m_local.get();<br />
          if ( localMap != null )<br />
          {<br />
               Object found = localMap.get( key );<br />
               if ( found != null )<br />
               {<br />
                    return found;<br />
               }<br />
          }</p>
<p>          synchronized( m_global )<br />
          {<br />
               Object found = m_global.get( key );<br />
               if ( found != null )<br />
               {<br />
                    if ( localMap == null )<br />
                    {<br />
                         localMap = new HashMap();<br />
                         m_local.put( localMap );<br />
                    }</p>
<p>                    localMap.put( key, found );<br />
               }<br />
               return found;<br />
          }<br />
     }</p>
<p>     put( key, value )<br />
     {<br />
          synchronized( m_global )<br />
          {<br />
               m_blobal.put( key, value );<br />
          }<br />
          Map localMap = m_local.get();<br />
          if ( localMap == null )<br />
          {<br />
               localMap = new HashMap();<br />
               m_local.set( localMap );<br />
          }<br />
          localMap.put( key, value );<br />
    }<br />
}</p>
<p>CacheC<br />
{<br />
     ThreadLocal m_threadLocal = new ThreadLocal();<br />
     Map m_global = new HashMap();</p>
<p>     get( key )<br />
     {<br />
          Map localMap = m_local.get();<br />
          if ( localMap != null )<br />
          {<br />
               Object found = localMap.get( key );<br />
               if ( found != null )<br />
               {<br />
                    return found;<br />
               }<br />
          }</p>
<p>          synchronized( m_global )<br />
          {<br />
               if ( localMap == m_global )<br />
               {<br />
                    return;<br />
               }</p>
<p>               m_local.set( m_global );<br />
               return m_global.get( key ):<br />
          }<br />
     }</p>
<p>     put( key, value )<br />
     {<br />
          synchronized( m_global )<br />
          {<br />
               m_global = m_global.clone();<br />
               m_global.put( key, value );<br />
               m_local.set( m_global );<br />
          }<br />
    }<br />
}</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Anton Tagunov</title>
		<link>http://www.symphonious.net/2004/08/17/string-interning-and-threads/comment-page-1/#comment-198</link>
		<dc:creator>Anton Tagunov</dc:creator>
		<pubDate>Thu, 01 Jan 1970 01:00:00 +0000</pubDate>
		<guid isPermaLink="false">http://localhost/wordpress/?p=203#comment-198</guid>
		<description>yes, in my previous post I should have done
s/m_local/m_threadLocal/g
</description>
		<content:encoded><![CDATA[<p>yes, in my previous post I should have done<br />
s/m_local/m_threadLocal/g</p>
]]></content:encoded>
	</item>
</channel>
</rss>
