-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocal-search.xml
executable file
·82 lines (39 loc) · 41.4 KB
/
local-search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>guava_cache的基本使用</title>
<link href="/2021/08/28/guava-cache/"/>
<url>/2021/08/28/guava-cache/</url>
<content type="html"><![CDATA[<h3 id="前言:"><a href="#前言:" class="headerlink" title="前言:"></a>前言:</h3><p>Guava 学习笔记,参考自Google Guava官方文档。</p><h2 id="Guava-Cache"><a href="#Guava-Cache" class="headerlink" title="Guava Cache"></a>Guava Cache</h2><p>@[toc]</p><h3 id="Cache的回收机制"><a href="#Cache的回收机制" class="headerlink" title="Cache的回收机制"></a>Cache的回收机制</h3><blockquote><p>既然是缓存,那么总会存在没有足够的内存缓存所有数据。Cache提供三大类回收机制。</p></blockquote><h4 id="基于容量回收"><a href="#基于容量回收" class="headerlink" title="基于容量回收"></a>基于容量回收</h4><blockquote><p>如果要规定缓存项的数目不超过固定值,只需使用<code>CacheBuilder.maximumSize(long)</code>]。缓存将尝试回收<strong>最近没有使用或总体上很少使用</strong>的缓存项。——<em>警告</em>:在缓存项的数目达到限定值之前,缓存就可能进行回收操作——通常来说,这种情况发生在缓存项的数目逼近限定值时。</p></blockquote><h4 id="基于定时回收"><a href="#基于定时回收" class="headerlink" title="基于定时回收"></a>基于定时回收</h4><blockquote><p><code>CacheBuilder</code>提供两种定时回收的方法:</p><ul><li><code>expireAfterAccess(long, TimeUnit)</code>:缓存项在给定时间内没有<strong>被读/写访问</strong>,则回收。请注意这种缓存的回收顺序和基于大小回收一样。</li><li><code>expireAfterWrite(long, TimeUnit)</code>:缓存项在给定时间’’内没有<strong>被写访问(创建或覆盖)</strong>,则回收。如果认为缓存数据总是在固定时候后变得陈旧不可用,这种回收方式是可取的。</li></ul></blockquote><h4 id="基于引用类型回收"><a href="#基于引用类型回收" class="headerlink" title="基于引用类型回收"></a>基于引用类型回收</h4><blockquote><p>通过使用<strong>弱引用的键、或弱引用的值、或软引用的值</strong>,Guava Cache可以把缓存设置为允许垃圾回收:</p><ul><li> <code>CacheBuilder.weakKeys()</code>:使用<strong>弱引用存储键</strong>。当键没有其它(强或软)引用时,缓存项可以被垃圾回收。因为垃圾回收仅依赖恒等式(==),使用弱引用键的缓存用==而不是equals比较键。</li><li> CacheBuilder.weakValue():使用<strong>弱引用存储值</strong>。当值没有其它(强或软)引用时,缓存项可以被垃圾回收。因为垃圾回收仅依赖恒等式(==),使用弱引用值的缓存用==而不是equals比较值。</li><li> <code>CacheBuilder.softValues()</code>:使用<strong>软引用存储值</strong>。软引用只有在<strong>响应内存</strong>需要时,才按照全局最近最少使用的顺序回收。考虑到使用软引用的性能影响,我们通常建议使用更有性能预测性的缓存大小限定(见上文,基于容量回收)。使用软引用值的缓存同样用==而不是equals比较值。</li></ul></blockquote><h3 id="具体功能使用"><a href="#具体功能使用" class="headerlink" title="具体功能使用"></a>具体功能使用</h3><h4 id="加载-CacheLoader"><a href="#加载-CacheLoader" class="headerlink" title="加载 CacheLoader"></a>加载 CacheLoader</h4><blockquote><p>创建CacheLoader实现load(方法即可。当使用get()方法的时候,要么返回容器中已经缓存的值,要么就是使用CacheLoader想缓存原子的加载新值。、</p><p>如果部分场景需要使用getAll(),可以重载CacheLoader.loadAll()提高效率。若不重载则会单独调用CacheLoader.load()进行加载。</p></blockquote><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><code class="hljs JAVA">LoadingCache<Key, Object> graphs = CacheBuilder.newBuilder()<br> .build(<br> <span class="hljs-comment">//</span><br> <span class="hljs-keyword">new</span> CacheLoader<Key, Object>() {<br> <span class="hljs-function"><span class="hljs-keyword">public</span> Graph <span class="hljs-title">load</span><span class="hljs-params">(Key key)</span> <span class="hljs-keyword">throws</span> AnyException </span>{<br> <span class="hljs-keyword">return</span> getObjectFromDb(key);<br> }<br> });<br></code></pre></td></tr></table></figure><h4 id="Callable"><a href="#Callable" class="headerlink" title="Callable"></a>Callable</h4><blockquote><p>方便自定义每次的获取逻辑, 原理跟CacheLoader.load()一致。 如果缓存中不存在,则调用callable()来进行获取放入缓存中。</p></blockquote><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><code class="hljs java">Cache<Key, Graph> cache = CacheBuilder.newBuilder()<br> .maximumSize(<span class="hljs-number">1000</span>)<br> .build(); <span class="hljs-comment">// look Ma, no CacheLoader</span><br>...<br><span class="hljs-keyword">try</span> {<br> <span class="hljs-comment">// If the key wasn't in the "easy to compute" group, we need to</span><br> <span class="hljs-comment">// do things the hard way.</span><br> cache.get(key, <span class="hljs-keyword">new</span> Callable<Key, Graph>() {<br> <span class="hljs-meta">@Override</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> Value <span class="hljs-title">call</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> AnyException </span>{<br> <span class="hljs-keyword">return</span> doThingsTheHardWay(key);<br> }<br> });<br>} <span class="hljs-keyword">catch</span> (ExecutionException e) {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> OtherException(e.getCause());<br>}<br></code></pre></td></tr></table></figure><h3 id="显式插入"><a href="#显式插入" class="headerlink" title="显式插入"></a>显式插入</h3><p>使用<code>cache.put(key, value)</code>方法可以直接向缓存中插入值,这会直接覆盖掉给定键之前映射的值。使用<code>Cache.asMap()</code>视图提供的任何方法也能修改缓存。但请注意,asMap视图的任何方法都<strong>不能保证缓存项被原子地加载到缓存中</strong>。进一步说,asMap视图的原子运算在Guava Cache的原子加载范畴之外,所以相比于<code>Cache.asMap().putIfAbsent(K, V),Cache.get(K, Callable<V>) </code>应该总是优先使用。 <strong>即更多的依赖自动加载而不是手动的进行添加。</strong></p><h3 id="元素移除监听器-removalListener"><a href="#元素移除监听器-removalListener" class="headerlink" title="元素移除监听器 removalListener"></a>元素移除监听器 removalListener</h3><p>通过<code>CacheBuilder.removalListener(RemovalListener)</code>你可以声明一个监听器,以便缓存项被移除时做一些额外操作。</p><h3 id="asMap视图"><a href="#asMap视图" class="headerlink" title="asMap视图"></a>asMap视图</h3><p>asMap视图提供了缓存的ConcurrentMap形式,但asMap视图与缓存的交互需要注意:</p><ul><li>cache.asMap()包含当前所有加载到缓存的项。因此相应地,cache.asMap().keySet()包含当前所有已加载键;</li><li>asMap().get(key)实质上等同于cache.getIfPresent(key),而且不会引起缓存项的加载。这和Map的语义约定一致。</li><li>所有<strong>读写操作都会重置相关缓存项的访问时间</strong>,包括Cache.asMap().get(Object)方法和Cache.asMap().put(K, V)方法,但不包括Cache.asMap().containsKey(Object)方法,也不包括在Cache.asMap()的集合视图上的操作。比如,遍历Cache.asMap().entrySet()不会重置缓存项的读取时间。</li></ul><h3 id="测试代码"><a href="#测试代码" class="headerlink" title="测试代码"></a>测试代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br></pre></td><td class="code"><pre><code class="hljs JAVA"><span class="hljs-keyword">package</span> com.justloseit.common.test.guavaTest.guavaCache;<br><br><span class="hljs-keyword">import</span> com.google.common.base.Optional;<br><span class="hljs-keyword">import</span> com.google.common.cache.*;<br><span class="hljs-keyword">import</span> com.google.common.collect.ImmutableMap;<br><br><br><span class="hljs-keyword">import</span> java.util.concurrent.ExecutionException;<br><span class="hljs-keyword">import</span> java.util.concurrent.Executors;<br><span class="hljs-keyword">import</span> java.util.concurrent.TimeUnit;<br><br><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@Classname</span> CacheTest</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@Description</span> guava缓存 Test</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@Author</span> lqhao</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@Date</span> 2021/8/16 15:48</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@Version</span> 1.0</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CacheTest</span> </span>{<br> <span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 移除监听器</span><br><span class="hljs-comment"> */</span><br> <span class="hljs-keyword">static</span> RemovalListener<Integer, Student> MY_LISTENER_01 = removal -> {<br> Student student = removal.getValue();<br> System.out.println(student.getName()+<span class="hljs-string">"被移除了"</span>);<br> };<br> <span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 异步移除监听器 需要添加异步执行的线程池</span><br><span class="hljs-comment"> */</span><br> <span class="hljs-keyword">static</span> RemovalListener<Integer, Student> MY_LISTENER_02=RemovalListeners.asynchronous(removal -> {<br> Student student = removal.getValue();<br> <span class="hljs-keyword">try</span> {<br> Thread.sleep(<span class="hljs-number">2000</span>);<br> } <span class="hljs-keyword">catch</span> (InterruptedException e) {<br> e.printStackTrace();<br> }<br> System.out.println(student.getName()+<span class="hljs-string">"被异步移除了"</span>);<br> }, Executors.newSingleThreadExecutor());<br><br> <span class="hljs-comment">/**</span><br><span class="hljs-comment"> * Guava缓存</span><br><span class="hljs-comment"> */</span><br> <span class="hljs-keyword">static</span> LoadingCache<Integer, Student> studentCaches = CacheBuilder.newBuilder().softValues()<br> .maximumSize(<span class="hljs-number">1</span>)<span class="hljs-comment">// 固定容器的大小</span><br> .expireAfterWrite(<span class="hljs-number">10</span>, TimeUnit.MINUTES)<span class="hljs-comment">//缓存项在给定时间内没有被写访问(创建或覆盖),则回收</span><br><span class="hljs-comment">// .removalListener(MY_LISTENER_01) //同步</span><br> .removalListener(MY_LISTENER_02) <span class="hljs-comment">//异步</span><br> .build(<br> <span class="hljs-comment">//缓存中不存在则主动的进行加载</span><br> <span class="hljs-keyword">new</span> CacheLoader<Integer, Student>() {<br> <span class="hljs-meta">@Override</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> Student <span class="hljs-title">load</span><span class="hljs-params">(Integer key)</span> </span>{<br> Optional<Student> optional=Student.get(key);<br> <span class="hljs-keyword">if</span> (optional.isPresent()){<br> <span class="hljs-keyword">return</span> optional.get();<br> }<span class="hljs-keyword">else</span>{<br> <span class="hljs-keyword">return</span> Student.valueOf(key, <span class="hljs-number">18</span>, <span class="hljs-string">"awake"</span>);<br> }<br> }<br> });<br><br> <span class="hljs-comment">/**</span><br><span class="hljs-comment"> * 主函数</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@param</span> args</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@throws</span> ExecutionException</span><br><span class="hljs-comment"> */</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> ExecutionException </span>{<br> System.out.println(studentCaches.get(<span class="hljs-number">1</span>));<br> System.out.println(studentCaches.get(<span class="hljs-number">0</span>));<br> System.out.println(studentCaches.size());<br><br> }<br><br><br> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Student</span></span>{<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> id;<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> age;<br> <span class="hljs-keyword">private</span> String name;<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> ImmutableMap<Integer, Student> studentImmutableMap=ImmutableMap.of(<br> <span class="hljs-number">1</span>, Student.valueOf(<span class="hljs-number">1</span>, <span class="hljs-number">18</span>, <span class="hljs-string">"lqhao"</span>),<br> <span class="hljs-number">2</span>, Student.valueOf(<span class="hljs-number">2</span>, <span class="hljs-number">19</span>, <span class="hljs-string">"zpwen"</span>),<br> <span class="hljs-number">3</span>, Student.valueOf(<span class="hljs-number">3</span>, <span class="hljs-number">20</span>, <span class="hljs-string">"qyyi"</span>)<br> );<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Optional<Student> <span class="hljs-title">get</span><span class="hljs-params">(Integer id)</span> </span>{<br> Student student=studentImmutableMap.get(id);<br> <span class="hljs-keyword">return</span> Optional.fromNullable(student);<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Student <span class="hljs-title">valueOf</span><span class="hljs-params">(<span class="hljs-keyword">int</span> id, <span class="hljs-keyword">int</span> age, String name)</span> </span>{<br> Student student=<span class="hljs-keyword">new</span> Student();<br> student.id=id;<br> student.age=age;<br> student.name=name;<br> <span class="hljs-keyword">return</span> student;<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getId</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> id;<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setId</span><span class="hljs-params">(<span class="hljs-keyword">int</span> id)</span> </span>{<br> <span class="hljs-keyword">this</span>.id = id;<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getAge</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> age;<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAge</span><span class="hljs-params">(<span class="hljs-keyword">int</span> age)</span> </span>{<br> <span class="hljs-keyword">this</span>.age = age;<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> name;<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setName</span><span class="hljs-params">(String name)</span> </span>{<br> <span class="hljs-keyword">this</span>.name = name;<br> }<br><br> <span class="hljs-meta">@Override</span><br> <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">toString</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"Student{"</span> +<br> <span class="hljs-string">"id="</span> + id +<br> <span class="hljs-string">", age="</span> + age +<br> <span class="hljs-string">", name='"</span> + name + <span class="hljs-string">'\''</span> +<br> <span class="hljs-string">'}'</span>;<br> }<br> }<br>}<br><br><br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>学习</category>
</categories>
<tags>
<tag>JAVA</tag>
</tags>
</entry>
<entry>
<title>java_Reference 四种引用及代码实例</title>
<link href="/2021/08/24/javReference/"/>
<url>/2021/08/24/javReference/</url>
<content type="html"><![CDATA[<h3 id="前言:"><a href="#前言:" class="headerlink" title="前言:"></a>前言:</h3><p>学习guavaCache的时候遇到的一些比较模糊的地方,之前复习过的,现在又忘了,写个blog记录一下下。</p><h3 id="Java-四种引用"><a href="#Java-四种引用" class="headerlink" title="Java 四种引用"></a>Java 四种引用</h3><h4 id="强引用-Strong-Reference"><a href="#强引用-Strong-Reference" class="headerlink" title="强引用 Strong Reference"></a>强引用 Strong Reference</h4><blockquote><p>日常开发我们锁创建的引用就是强引用。例子:Student obj=new Student();</p></blockquote><h4 id="软引用-Solf-Reference"><a href="#软引用-Solf-Reference" class="headerlink" title="软引用 Solf Reference"></a>软引用 Solf Reference</h4><blockquote><p>软引用是用来描述一些非必需但仍有用的对象。<strong>在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象,如果回收了软引用对象之后仍然没有足够的内存,才会抛出内存溢出异常</strong>。</p><p>Java中需要使用SoftReference来使用软引用</p><p>如果一个对象<strong>惟一剩下的引用是软引用</strong>,那么该对象是软可及的(softly reachable)。垃圾收集器并不像其收集弱可及的对象一样尽量地收集软可及的对象,相反,它只在真正 “需要” 内存时才收集软可及的对象。</p></blockquote><h4 id="弱引用-Weak-Reference"><a href="#弱引用-Weak-Reference" class="headerlink" title="弱引用 Weak Reference"></a>弱引用 Weak Reference</h4><blockquote><p>弱引用的引用强度比软引用要更弱一些,<strong>无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收</strong>。在 JDK1.2 之后,用 java.lang.ref.WeakReference 来表示弱引用。</p><p>如果一个对象<strong>惟一剩下的引用是弱引用</strong>,那么该对象是软可及的(softly reachable)。垃圾收集器会尽量地收集弱可及的对象。</p></blockquote><h4 id="虚引用-Phantom-Reference"><a href="#虚引用-Phantom-Reference" class="headerlink" title="虚引用 Phantom Reference"></a>虚引用 Phantom Reference</h4><blockquote><p>虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收,在 JDK1.2 之后,用 PhantomReference 类来表示,通过查看这个类的源码,发现它只有一个构造函数和一个 get() 方法,而且它的 get() 方法仅仅是返回一个null,也就是说将永远无法通过虚引用来获取对象,虚引用必须要和 ReferenceQueue 引用队列一起使用。</p></blockquote><h4 id="引用队列(ReferenceQueue)"><a href="#引用队列(ReferenceQueue)" class="headerlink" title="引用队列(ReferenceQueue)"></a>引用队列(ReferenceQueue)</h4><blockquote><p>引用队列可以与软引用、弱引用以及虚引用一起配合使用,当垃圾回收器准备回收一个对象时,如果发现它还有引用,那么就会在回收对象之前,把这个引用加入到与之关联的引用队列中去。程序可以通过判断引用队列中是否已经加入了引用,来判断被引用的对象是否将要被垃圾回收,这样就可以在对象被回收之前采取一些必要的措施。</p></blockquote><h3 id="各个引用类型测试代码"><a href="#各个引用类型测试代码" class="headerlink" title="各个引用类型测试代码"></a>各个引用类型测试代码</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-comment">/**</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@Classname</span> FourReferenceTest</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@Description</span> 四种引用的测试 配置参数 -Xms2M -Xmx3M,将 JVM 的初始内存设为2M,最大可用内存为 3M。</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@Author</span> lqhao</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@Date</span> 2021/8/17 11:32</span><br><span class="hljs-comment"> * <span class="hljs-doctag">@Version</span> 1.0</span><br><span class="hljs-comment"> */</span><br><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FourReferenceTest</span> </span>{<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> List<Object> list = <span class="hljs-keyword">new</span> ArrayList<>();<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> ReferenceQueue<<span class="hljs-keyword">byte</span>[]> rq = <span class="hljs-keyword">new</span> ReferenceQueue<<span class="hljs-keyword">byte</span>[]>();<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> _1M = <span class="hljs-number">1024</span>*<span class="hljs-number">1024</span>;<br><br> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{<br> <span class="hljs-comment">//测试强引用</span><br><span class="hljs-comment">// testStrongReference();</span><br> <span class="hljs-comment">//测试弱引用</span><br><span class="hljs-comment">// testSoftReference();</span><br> <span class="hljs-comment">//测试强引用</span><br><span class="hljs-comment">// testWeakReference();</span><br> <span class="hljs-comment">//测试引用队列</span><br> testReferenceQueue();<br> }<br> <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">testStrongReference</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-comment">// 当 new byte为 1M 时,程序运行正常</span><br><span class="hljs-comment">// byte[] buff = new byte[1024 * 1024 * 1];</span><br> <span class="hljs-comment">// 当 new byte为 3M 时,程序直接报错,强引用并不会被回收</span><br> <span class="hljs-keyword">byte</span>[] buff = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[_1M * <span class="hljs-number">3</span>];<br> }<br> <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">testSoftReference</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">10</span>; i++) {<br> <span class="hljs-keyword">byte</span>[] buff = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[_1M];<br> SoftReference<<span class="hljs-keyword">byte</span>[]> sr = <span class="hljs-keyword">new</span> SoftReference<>(buff);<br> list.add(sr);<br> }<br><br> System.gc(); <span class="hljs-comment">//主动通知垃圾回收</span><br><br> <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i < list.size(); i++){<br> Object obj = ((SoftReference) list.get(i)).get();<br> System.out.println(obj);<br> }<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">testWeakReference</span><span class="hljs-params">()</span> </span>{<br> <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">10</span>; i++) {<br> <span class="hljs-keyword">byte</span>[] buff = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[_1M];<br> WeakReference<<span class="hljs-keyword">byte</span>[]> sr = <span class="hljs-keyword">new</span> WeakReference<>(buff);<br> list.add(sr);<br> }<br><br> System.gc(); <span class="hljs-comment">//主动通知垃圾回收</span><br><br> <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i < list.size(); i++){<br> Object obj = ((WeakReference) list.get(i)).get();<br> System.out.println(obj);<br> }<br> }<br><br> <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">testReferenceQueue</span><span class="hljs-params">()</span></span>{<br> Object value = <span class="hljs-keyword">new</span> Object();<br> Map<Object, Object> map = <span class="hljs-keyword">new</span> HashMap<>();<br> Thread thread = <span class="hljs-keyword">new</span> Thread(() -> {<br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-keyword">int</span> cnt = <span class="hljs-number">0</span>;<br> WeakReference<<span class="hljs-keyword">byte</span>[]> k;<br> <span class="hljs-keyword">while</span>((k = (WeakReference) rq.remove()) != <span class="hljs-keyword">null</span>) {<br> System.out.println((cnt++) + <span class="hljs-string">"回收了:"</span> + k);<br> }<br> } <span class="hljs-keyword">catch</span>(InterruptedException e) {<br> <span class="hljs-comment">//结束循环</span><br> }<br> });<br> thread.setDaemon(<span class="hljs-keyword">true</span>);<br> thread.start();<br><br> <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>;i < <span class="hljs-number">1000</span>;i++) {<br> <span class="hljs-keyword">byte</span>[] bytes = <span class="hljs-keyword">new</span> <span class="hljs-keyword">byte</span>[_1M];<br> WeakReference<<span class="hljs-keyword">byte</span>[]> weakReference = <span class="hljs-keyword">new</span> WeakReference<<span class="hljs-keyword">byte</span>[]>(bytes, rq);<br> map.put(weakReference, value);<br> }<br> System.out.println(<span class="hljs-string">"map.size->"</span> + map.size());<br> }<br>}<br></code></pre></td></tr></table></figure>]]></content>
<categories>
<category>学习</category>
</categories>
<tags>
<tag>JAVA</tag>
</tags>
</entry>
<entry>
<title>Just lose it</title>
<link href="/2021/08/14/it/"/>
<url>/2021/08/14/it/</url>
<content type="html"><![CDATA[<p>各位读者:</p><p> 大家好。经过了半个多月的酝酿,awakeyoyoyo①终于下定决心,重新拾起写博客的习惯。自始第一件事情就是将之前大三写的卢瑟②博客网站彻底关闭。蛮不舍的。“上一次这么不舍的时候,还是上一次。”</p><blockquote><p>① 昔日博客网站的URL,根据站长花名阿围音译而来,由于不可抗拒因数(穷),买不起awake.com域名,无奈加以三个yo为自己呐喊。</p><p>② 出自人物NBA火箭队名宿卢瑟·海德,音译过来即为loser。</p></blockquote><p> 由于阿围经常性不间断不想学习。导致之前的博客网站疏于管理,于前不久由莫名其妙的BUG影响已经崩了,说来惭愧作为站长且唯一开发者的ta,也是无意间上班摸鱼手滑点了点那熟悉的浏览器书签才发现。</p><blockquote><p>侧面反映博客网站极少更新以至于无人问津。</p></blockquote><p> 自2018年”与我常在’Blog”③建站而来,该博客网站从来没有在崩溃’404 NOT FOUND’之后的24小时以内未被人@提醒。如果按照阿围写本文的时间来算,网站累计崩溃时长已超过几个多月,成为近3年来最简单无声的落幕谢场。</p><blockquote><p>③ 阿围的第二个发布于互联网上的网站。代表着当时阿围编程的最高水平。现在看来随便来个黑猫,白猫看上几分钟入门教程都可以用Hexo搭建一个比其酷炫百倍千倍的博客网站。从而成为一只有用的猫。</p></blockquote><p> 但是,简单的鼓掌,简单的谢场,永远不是完场;或者是沉迷了许久鸡汤,又或者是最近工作摸鱼过多心中有愧,阿围又开始为他下一阶段的目标制定大跃进计划,美其名为下一个五年计划。而重塑“与我常在’Blog’“就是这个计划的重要一环。</p><p> 阿围的博客网站的名称不忘初心,依旧是熟悉的”与我常在‘Blog”,该网站是基于Hexo+Github pages来搭建的,走的是极致的省钱模式。省去了服务器钱,省去了域名的钱,换来的是其他读者可能需要翻墙或者该host文件才可以访问到。阿围陈述道:“无所谓啦,反正也没啥人看是吧,Just lose it~~~”</p><p> 由”以前的怯,就输一辈子“到“Just lose it”。一个黄昏,广州珠江边的风刚停,天上映着粉色的晚霞。街上的车、街上的人都在赶着做某件事,而啊围一直在看云。那一瞬间,他忽然感觉到,自己可能真的要融入这个打工人的团体了。啊围意识到,网上流传的躺平的人,并不是害怕失败,而是害怕每天坐着重复的事情,走着重复的路。</p><p> 看着街上的人来人往,阿围眼光一刻也没有多停留,因为他不知道自己以后是否也会成为其中一员,他也不知道自己是否可以在坚持写博客这条路上走多久。生活嘛,本来就应该用来享受,而不是每天用一句“怯,就输一辈子”来让自己持续奋斗下去。</p><p> 还是那句话退一寸有退一寸的欢喜。Just lost it. </p><blockquote><p>在我们心里,just lose it的认输心态,绝非向命运低头,放弃反抗的懦夫行径。恰恰相反,它告诉我们,要从“从来如此便是对的”的逻辑中跳脱出来,追问自己的价值,在无人经过的荒芜中,走出一条新的路。</p><p> 出自 北大中文男足 Just lose it</p></blockquote><p> 本文参考文献——–北大中文男足公众号多篇推送</p>]]></content>
<categories>
<category>生活</category>
</categories>
<tags>
<tag>情绪泛滥</tag>
</tags>
</entry>
</search>