|
| 1 | +<?xml version="1.0" encoding="utf-8"?> |
| 2 | +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" |
| 3 | +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
| 4 | +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> |
| 5 | +<head> |
| 6 | +<title>资源争用模型(泛多线程编程)</title> |
| 7 | +<!-- 2017-09-18 周一 23:19 --> |
| 8 | +<meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> |
| 9 | +<meta name="generator" content="Org-mode" /> |
| 10 | +<meta name="author" content="王月阳" /> |
| 11 | +<meta name="description" content="讲解资源争用模型,如何解决资源争用过程中的资源安全问题。Java又是如何实现资源争用的。" |
| 12 | + /> |
| 13 | +<meta name="keywords" content="Java concurrenty 多线程 资源争用 Java内存模型 AQS Java锁 MVCC" /> |
| 14 | +<style type="text/css"> |
| 15 | + <!--/*--><![CDATA[/*><!--*/ |
| 16 | + .title { text-align: center; } |
| 17 | + .todo { font-family: monospace; color: red; } |
| 18 | + .done { color: green; } |
| 19 | + .tag { background-color: #eee; font-family: monospace; |
| 20 | + padding: 2px; font-size: 80%; font-weight: normal; } |
| 21 | + .timestamp { color: #bebebe; } |
| 22 | + .timestamp-kwd { color: #5f9ea0; } |
| 23 | + .right { margin-left: auto; margin-right: 0px; text-align: right; } |
| 24 | + .left { margin-left: 0px; margin-right: auto; text-align: left; } |
| 25 | + .center { margin-left: auto; margin-right: auto; text-align: center; } |
| 26 | + .underline { text-decoration: underline; } |
| 27 | + #postamble p, #preamble p { font-size: 90%; margin: .2em; } |
| 28 | + p.verse { margin-left: 3%; } |
| 29 | + pre { |
| 30 | + border: 1px solid #ccc; |
| 31 | + box-shadow: 3px 3px 3px #eee; |
| 32 | + padding: 8pt; |
| 33 | + font-family: monospace; |
| 34 | + overflow: auto; |
| 35 | + margin: 1.2em; |
| 36 | + } |
| 37 | + pre.src { |
| 38 | + position: relative; |
| 39 | + overflow: visible; |
| 40 | + padding-top: 1.2em; |
| 41 | + } |
| 42 | + pre.src:before { |
| 43 | + display: none; |
| 44 | + position: absolute; |
| 45 | + background-color: white; |
| 46 | + top: -10px; |
| 47 | + right: 10px; |
| 48 | + padding: 3px; |
| 49 | + border: 1px solid black; |
| 50 | + } |
| 51 | + pre.src:hover:before { display: inline;} |
| 52 | + pre.src-sh:before { content: 'sh'; } |
| 53 | + pre.src-bash:before { content: 'sh'; } |
| 54 | + pre.src-emacs-lisp:before { content: 'Emacs Lisp'; } |
| 55 | + pre.src-R:before { content: 'R'; } |
| 56 | + pre.src-perl:before { content: 'Perl'; } |
| 57 | + pre.src-java:before { content: 'Java'; } |
| 58 | + pre.src-sql:before { content: 'SQL'; } |
| 59 | + |
| 60 | + table { border-collapse:collapse; } |
| 61 | + caption.t-above { caption-side: top; } |
| 62 | + caption.t-bottom { caption-side: bottom; } |
| 63 | + td, th { vertical-align:top; } |
| 64 | + th.right { text-align: center; } |
| 65 | + th.left { text-align: center; } |
| 66 | + th.center { text-align: center; } |
| 67 | + td.right { text-align: right; } |
| 68 | + td.left { text-align: left; } |
| 69 | + td.center { text-align: center; } |
| 70 | + dt { font-weight: bold; } |
| 71 | + .footpara:nth-child(2) { display: inline; } |
| 72 | + .footpara { display: block; } |
| 73 | + .footdef { margin-bottom: 1em; } |
| 74 | + .figure { padding: 1em; } |
| 75 | + .figure p { text-align: center; } |
| 76 | + .inlinetask { |
| 77 | + padding: 10px; |
| 78 | + border: 2px solid gray; |
| 79 | + margin: 10px; |
| 80 | + background: #ffffcc; |
| 81 | + } |
| 82 | + #org-div-home-and-up |
| 83 | + { text-align: right; font-size: 70%; white-space: nowrap; } |
| 84 | + textarea { overflow-x: auto; } |
| 85 | + .linenr { font-size: smaller } |
| 86 | + .code-highlighted { background-color: #ffff00; } |
| 87 | + .org-info-js_info-navigation { border-style: none; } |
| 88 | + #org-info-js_console-label |
| 89 | + { font-size: 10px; font-weight: bold; white-space: nowrap; } |
| 90 | + .org-info-js_search-highlight |
| 91 | + { background-color: #ffff00; color: #000000; font-weight: bold; } |
| 92 | + /*]]>*/--> |
| 93 | +</style> |
| 94 | +<script type="text/javascript"> |
| 95 | +/* |
| 96 | +@licstart The following is the entire license notice for the |
| 97 | +JavaScript code in this tag. |
| 98 | +
|
| 99 | +Copyright (C) 2012-2013 Free Software Foundation, Inc. |
| 100 | +
|
| 101 | +The JavaScript code in this tag is free software: you can |
| 102 | +redistribute it and/or modify it under the terms of the GNU |
| 103 | +General Public License (GNU GPL) as published by the Free Software |
| 104 | +Foundation, either version 3 of the License, or (at your option) |
| 105 | +any later version. The code is distributed WITHOUT ANY WARRANTY; |
| 106 | +without even the implied warranty of MERCHANTABILITY or FITNESS |
| 107 | +FOR A PARTICULAR PURPOSE. See the GNU GPL for more details. |
| 108 | +
|
| 109 | +As additional permission under GNU GPL version 3 section 7, you |
| 110 | +may distribute non-source (e.g., minimized or compacted) forms of |
| 111 | +that code without the copy of the GNU GPL normally required by |
| 112 | +section 4, provided you include this license notice and a URL |
| 113 | +through which recipients can access the Corresponding Source. |
| 114 | +
|
| 115 | +
|
| 116 | +@licend The above is the entire license notice |
| 117 | +for the JavaScript code in this tag. |
| 118 | +*/ |
| 119 | +<!--/*--><![CDATA[/*><!--*/ |
| 120 | + function CodeHighlightOn(elem, id) |
| 121 | + { |
| 122 | + var target = document.getElementById(id); |
| 123 | + if(null != target) { |
| 124 | + elem.cacheClassElem = elem.className; |
| 125 | + elem.cacheClassTarget = target.className; |
| 126 | + target.className = "code-highlighted"; |
| 127 | + elem.className = "code-highlighted"; |
| 128 | + } |
| 129 | + } |
| 130 | + function CodeHighlightOff(elem, id) |
| 131 | + { |
| 132 | + var target = document.getElementById(id); |
| 133 | + if(elem.cacheClassElem) |
| 134 | + elem.className = elem.cacheClassElem; |
| 135 | + if(elem.cacheClassTarget) |
| 136 | + target.className = elem.cacheClassTarget; |
| 137 | + } |
| 138 | +/*]]>*///--> |
| 139 | +</script> |
| 140 | +</head> |
| 141 | +<body> |
| 142 | +<div id="content"> |
| 143 | +<h1 class="title">资源争用模型(泛多线程编程)</h1> |
| 144 | +<div id="table-of-contents"> |
| 145 | +<h2>Table of Contents</h2> |
| 146 | +<div id="text-table-of-contents"> |
| 147 | +<ul> |
| 148 | +<li><a href="#sec-1">1. 线程的演进</a> |
| 149 | +<ul> |
| 150 | +<li><a href="#sec-1-1">1.1. 从单道程序到多道程序,从多进程到多线程</a></li> |
| 151 | +</ul> |
| 152 | +</li> |
| 153 | +<li><a href="#sec-2">2. 线程的生命周期</a> |
| 154 | +<ul> |
| 155 | +<li><a href="#sec-2-1">2.1. 线程状态</a></li> |
| 156 | +<li><a href="#sec-2-2">2.2. 线程状态之间的转换</a></li> |
| 157 | +</ul> |
| 158 | +</li> |
| 159 | +<li><a href="#sec-3">3. 资源争用模型</a> |
| 160 | +<ul> |
| 161 | +<li><a href="#sec-3-1">3.1. 资源争用模型的含义</a></li> |
| 162 | +<li><a href="#sec-3-2">3.2. 例子</a></li> |
| 163 | +<li><a href="#sec-3-3">3.3. 从争的角度解决问题(排队模型)</a> |
| 164 | +<ul> |
| 165 | +<li><a href="#sec-3-3-1">3.3.1. 排队的本质就是有序</a></li> |
| 166 | +<li><a href="#sec-3-3-2">3.3.2. 排队的实现</a></li> |
| 167 | +</ul> |
| 168 | +</li> |
| 169 | +<li><a href="#sec-3-4">3.4. 从资源的角度解决问题</a> |
| 170 | +<ul> |
| 171 | +<li><a href="#sec-3-4-1">3.4.1. 不共享资源 CopyOnWrite</a></li> |
| 172 | +<li><a href="#sec-3-4-2">3.4.2. 资源不可变 ImmutableData</a></li> |
| 173 | +</ul> |
| 174 | +</li> |
| 175 | +<li><a href="#sec-3-5">3.5. 更细的粒度</a> |
| 176 | +<ul> |
| 177 | +<li><a href="#sec-3-5-1">3.5.1. 共享锁与排他锁</a></li> |
| 178 | +<li><a href="#sec-3-5-2">3.5.2. MVCC</a></li> |
| 179 | +</ul> |
| 180 | +</li> |
| 181 | +</ul> |
| 182 | +</li> |
| 183 | +<li><a href="#sec-4">4. Java内存模型与资源争用</a> |
| 184 | +<ul> |
| 185 | +<li><a href="#sec-4-1">4.1. Java内存模型与运行时内存分布,分析被争用的资源</a></li> |
| 186 | +<li><a href="#sec-4-2">4.2. Java如何使用不共享内存模型解决线程安全问题</a> |
| 187 | +<ul> |
| 188 | +<li><a href="#sec-4-2-1">4.2.1. copyOnWriteList</a></li> |
| 189 | +<li><a href="#sec-4-2-2">4.2.2. ThreadLocal</a></li> |
| 190 | +</ul> |
| 191 | +</li> |
| 192 | +<li><a href="#sec-4-3">4.3. Java如果使用不可变资源模型解决线程安全问题</a> |
| 193 | +<ul> |
| 194 | +<li><a href="#sec-4-3-1">4.3.1. Final关键字</a></li> |
| 195 | +<li><a href="#sec-4-3-2">4.3.2. String类</a></li> |
| 196 | +</ul> |
| 197 | +</li> |
| 198 | +<li><a href="#sec-4-4">4.4. Java如何使用排队模型解决线程安全问题</a> |
| 199 | +<ul> |
| 200 | +<li><a href="#sec-4-4-1">4.4.1. synchronized的用法</a></li> |
| 201 | +<li><a href="#sec-4-4-2">4.4.2. Java对象头</a></li> |
| 202 | +<li><a href="#sec-4-4-3">4.4.3. LockSupport+cas+CHL队列构成了Java锁的基础</a></li> |
| 203 | +<li><a href="#sec-4-4-4">4.4.4. AQS解读</a></li> |
| 204 | +<li><a href="#sec-4-4-5">4.4.5. 读写分离</a></li> |
| 205 | +<li><a href="#sec-4-4-6">4.4.6. 写写分离</a></li> |
| 206 | +<li><a href="#sec-4-4-7">4.4.7. CountDownLatch</a></li> |
| 207 | +<li><a href="#sec-4-4-8">4.4.8. FutureTask</a></li> |
| 208 | +<li><a href="#sec-4-4-9">4.4.9. Semaphore</a></li> |
| 209 | +</ul> |
| 210 | +</li> |
| 211 | +</ul> |
| 212 | +</li> |
| 213 | +<li><a href="#sec-5">5. Java线程管理</a> |
| 214 | +<ul> |
| 215 | +<li><a href="#sec-5-1">5.1. ThreadPoolExecutor解读</a> |
| 216 | +<ul> |
| 217 | +<li><a href="#sec-5-1-1">5.1.1. 参数说明</a></li> |
| 218 | +<li><a href="#sec-5-1-2">5.1.2. 核心方法解读</a></li> |
| 219 | +</ul> |
| 220 | +</li> |
| 221 | +</ul> |
| 222 | +</li> |
| 223 | +<li><a href="#sec-6">6. 分布式系统中的资源争用</a> |
| 224 | +<ul> |
| 225 | +<li><a href="#sec-6-1">6.1. Redis的单线程实现–排队模型</a></li> |
| 226 | +<li><a href="#sec-6-2">6.2. Zookeeper一主多从–排队+读写分离</a></li> |
| 227 | +</ul> |
| 228 | +</li> |
| 229 | +</ul> |
| 230 | +</div> |
| 231 | +</div> |
| 232 | + |
| 233 | +<div id="outline-container-sec-1" class="outline-2"> |
| 234 | +<h2 id="sec-1"><span class="section-number-2">1</span> 线程的演进</h2> |
| 235 | +<div class="outline-text-2" id="text-1"> |
| 236 | +</div><div id="outline-container-sec-1-1" class="outline-3"> |
| 237 | +<h3 id="sec-1-1"><span class="section-number-3">1.1</span> 从单道程序到多道程序,从多进程到多线程</h3> |
| 238 | +</div> |
| 239 | +</div> |
| 240 | + |
| 241 | +<div id="outline-container-sec-2" class="outline-2"> |
| 242 | +<h2 id="sec-2"><span class="section-number-2">2</span> 线程的生命周期</h2> |
| 243 | +<div class="outline-text-2" id="text-2"> |
| 244 | +</div><div id="outline-container-sec-2-1" class="outline-3"> |
| 245 | +<h3 id="sec-2-1"><span class="section-number-3">2.1</span> 线程状态</h3> |
| 246 | +</div> |
| 247 | +<div id="outline-container-sec-2-2" class="outline-3"> |
| 248 | +<h3 id="sec-2-2"><span class="section-number-3">2.2</span> 线程状态之间的转换</h3> |
| 249 | +</div> |
| 250 | +</div> |
| 251 | + |
| 252 | +<div id="outline-container-sec-3" class="outline-2"> |
| 253 | +<h2 id="sec-3"><span class="section-number-2">3</span> 资源争用模型</h2> |
| 254 | +<div class="outline-text-2" id="text-3"> |
| 255 | +</div><div id="outline-container-sec-3-1" class="outline-3"> |
| 256 | +<h3 id="sec-3-1"><span class="section-number-3">3.1</span> 资源争用模型的含义</h3> |
| 257 | +</div> |
| 258 | + |
| 259 | +<div id="outline-container-sec-3-2" class="outline-3"> |
| 260 | +<h3 id="sec-3-2"><span class="section-number-3">3.2</span> 例子</h3> |
| 261 | +</div> |
| 262 | + |
| 263 | +<div id="outline-container-sec-3-3" class="outline-3"> |
| 264 | +<h3 id="sec-3-3"><span class="section-number-3">3.3</span> 从争的角度解决问题(排队模型)</h3> |
| 265 | +<div class="outline-text-3" id="text-3-3"> |
| 266 | +</div><div id="outline-container-sec-3-3-1" class="outline-4"> |
| 267 | +<h4 id="sec-3-3-1"><span class="section-number-4">3.3.1</span> 排队的本质就是有序</h4> |
| 268 | +</div> |
| 269 | +<div id="outline-container-sec-3-3-2" class="outline-4"> |
| 270 | +<h4 id="sec-3-3-2"><span class="section-number-4">3.3.2</span> 排队的实现</h4> |
| 271 | +</div> |
| 272 | +</div> |
| 273 | + |
| 274 | +<div id="outline-container-sec-3-4" class="outline-3"> |
| 275 | +<h3 id="sec-3-4"><span class="section-number-3">3.4</span> 从资源的角度解决问题</h3> |
| 276 | +<div class="outline-text-3" id="text-3-4"> |
| 277 | +</div><div id="outline-container-sec-3-4-1" class="outline-4"> |
| 278 | +<h4 id="sec-3-4-1"><span class="section-number-4">3.4.1</span> 不共享资源 CopyOnWrite</h4> |
| 279 | +</div> |
| 280 | +<div id="outline-container-sec-3-4-2" class="outline-4"> |
| 281 | +<h4 id="sec-3-4-2"><span class="section-number-4">3.4.2</span> 资源不可变 ImmutableData</h4> |
| 282 | +</div> |
| 283 | +</div> |
| 284 | + |
| 285 | +<div id="outline-container-sec-3-5" class="outline-3"> |
| 286 | +<h3 id="sec-3-5"><span class="section-number-3">3.5</span> 更细的粒度</h3> |
| 287 | +<div class="outline-text-3" id="text-3-5"> |
| 288 | +</div><div id="outline-container-sec-3-5-1" class="outline-4"> |
| 289 | +<h4 id="sec-3-5-1"><span class="section-number-4">3.5.1</span> 共享锁与排他锁</h4> |
| 290 | +</div> |
| 291 | +<div id="outline-container-sec-3-5-2" class="outline-4"> |
| 292 | +<h4 id="sec-3-5-2"><span class="section-number-4">3.5.2</span> MVCC</h4> |
| 293 | +</div> |
| 294 | +</div> |
| 295 | +</div> |
| 296 | + |
| 297 | +<div id="outline-container-sec-4" class="outline-2"> |
| 298 | +<h2 id="sec-4"><span class="section-number-2">4</span> Java内存模型与资源争用</h2> |
| 299 | +<div class="outline-text-2" id="text-4"> |
| 300 | +<p> |
| 301 | +用一个状态位标识资源状态:可用不可用,可写不可写,可读不可读 |
| 302 | +</p> |
| 303 | +</div> |
| 304 | +<div id="outline-container-sec-4-1" class="outline-3"> |
| 305 | +<h3 id="sec-4-1"><span class="section-number-3">4.1</span> Java内存模型与运行时内存分布,分析被争用的资源</h3> |
| 306 | +</div> |
| 307 | +<div id="outline-container-sec-4-2" class="outline-3"> |
| 308 | +<h3 id="sec-4-2"><span class="section-number-3">4.2</span> Java如何使用不共享内存模型解决线程安全问题</h3> |
| 309 | +<div class="outline-text-3" id="text-4-2"> |
| 310 | +</div><div id="outline-container-sec-4-2-1" class="outline-4"> |
| 311 | +<h4 id="sec-4-2-1"><span class="section-number-4">4.2.1</span> copyOnWriteList</h4> |
| 312 | +</div> |
| 313 | +<div id="outline-container-sec-4-2-2" class="outline-4"> |
| 314 | +<h4 id="sec-4-2-2"><span class="section-number-4">4.2.2</span> ThreadLocal</h4> |
| 315 | +</div> |
| 316 | +</div> |
| 317 | + |
| 318 | +<div id="outline-container-sec-4-3" class="outline-3"> |
| 319 | +<h3 id="sec-4-3"><span class="section-number-3">4.3</span> Java如果使用不可变资源模型解决线程安全问题</h3> |
| 320 | +<div class="outline-text-3" id="text-4-3"> |
| 321 | +</div><div id="outline-container-sec-4-3-1" class="outline-4"> |
| 322 | +<h4 id="sec-4-3-1"><span class="section-number-4">4.3.1</span> Final关键字</h4> |
| 323 | +</div> |
| 324 | +<div id="outline-container-sec-4-3-2" class="outline-4"> |
| 325 | +<h4 id="sec-4-3-2"><span class="section-number-4">4.3.2</span> String类</h4> |
| 326 | +</div> |
| 327 | +</div> |
| 328 | + |
| 329 | +<div id="outline-container-sec-4-4" class="outline-3"> |
| 330 | +<h3 id="sec-4-4"><span class="section-number-3">4.4</span> Java如何使用排队模型解决线程安全问题</h3> |
| 331 | +<div class="outline-text-3" id="text-4-4"> |
| 332 | +</div><div id="outline-container-sec-4-4-1" class="outline-4"> |
| 333 | +<h4 id="sec-4-4-1"><span class="section-number-4">4.4.1</span> synchronized的用法</h4> |
| 334 | +</div> |
| 335 | +<div id="outline-container-sec-4-4-2" class="outline-4"> |
| 336 | +<h4 id="sec-4-4-2"><span class="section-number-4">4.4.2</span> Java对象头</h4> |
| 337 | +</div> |
| 338 | +<div id="outline-container-sec-4-4-3" class="outline-4"> |
| 339 | +<h4 id="sec-4-4-3"><span class="section-number-4">4.4.3</span> LockSupport+cas+CHL队列构成了Java锁的基础</h4> |
| 340 | +</div> |
| 341 | +<div id="outline-container-sec-4-4-4" class="outline-4"> |
| 342 | +<h4 id="sec-4-4-4"><span class="section-number-4">4.4.4</span> AQS解读</h4> |
| 343 | +</div> |
| 344 | +<div id="outline-container-sec-4-4-5" class="outline-4"> |
| 345 | +<h4 id="sec-4-4-5"><span class="section-number-4">4.4.5</span> 读写分离</h4> |
| 346 | +<div class="outline-text-4" id="text-4-4-5"> |
| 347 | +</div><ol class="org-ol"><li><a id="sec-4-4-5-1" name="sec-4-4-5-1"></a>ReentrantReadWriteLock<br /></li></ol> |
| 348 | +</div> |
| 349 | +<div id="outline-container-sec-4-4-6" class="outline-4"> |
| 350 | +<h4 id="sec-4-4-6"><span class="section-number-4">4.4.6</span> 写写分离</h4> |
| 351 | +<div class="outline-text-4" id="text-4-4-6"> |
| 352 | +</div><ol class="org-ol"><li><a id="sec-4-4-6-1" name="sec-4-4-6-1"></a>ConcurrentHashMap<br /></li></ol> |
| 353 | +</div> |
| 354 | +<div id="outline-container-sec-4-4-7" class="outline-4"> |
| 355 | +<h4 id="sec-4-4-7"><span class="section-number-4">4.4.7</span> CountDownLatch</h4> |
| 356 | +</div> |
| 357 | +<div id="outline-container-sec-4-4-8" class="outline-4"> |
| 358 | +<h4 id="sec-4-4-8"><span class="section-number-4">4.4.8</span> FutureTask</h4> |
| 359 | +</div> |
| 360 | +<div id="outline-container-sec-4-4-9" class="outline-4"> |
| 361 | +<h4 id="sec-4-4-9"><span class="section-number-4">4.4.9</span> Semaphore</h4> |
| 362 | +</div> |
| 363 | +</div> |
| 364 | +</div> |
| 365 | + |
| 366 | +<div id="outline-container-sec-5" class="outline-2"> |
| 367 | +<h2 id="sec-5"><span class="section-number-2">5</span> Java线程管理</h2> |
| 368 | +<div class="outline-text-2" id="text-5"> |
| 369 | +</div><div id="outline-container-sec-5-1" class="outline-3"> |
| 370 | +<h3 id="sec-5-1"><span class="section-number-3">5.1</span> ThreadPoolExecutor解读</h3> |
| 371 | +<div class="outline-text-3" id="text-5-1"> |
| 372 | +</div><div id="outline-container-sec-5-1-1" class="outline-4"> |
| 373 | +<h4 id="sec-5-1-1"><span class="section-number-4">5.1.1</span> 参数说明</h4> |
| 374 | +</div> |
| 375 | +<div id="outline-container-sec-5-1-2" class="outline-4"> |
| 376 | +<h4 id="sec-5-1-2"><span class="section-number-4">5.1.2</span> 核心方法解读</h4> |
| 377 | +</div> |
| 378 | +</div> |
| 379 | +</div> |
| 380 | + |
| 381 | +<div id="outline-container-sec-6" class="outline-2"> |
| 382 | +<h2 id="sec-6"><span class="section-number-2">6</span> 分布式系统中的资源争用</h2> |
| 383 | +<div class="outline-text-2" id="text-6"> |
| 384 | +</div><div id="outline-container-sec-6-1" class="outline-3"> |
| 385 | +<h3 id="sec-6-1"><span class="section-number-3">6.1</span> Redis的单线程实现–排队模型</h3> |
| 386 | +</div> |
| 387 | +<div id="outline-container-sec-6-2" class="outline-3"> |
| 388 | +<h3 id="sec-6-2"><span class="section-number-3">6.2</span> Zookeeper一主多从–排队+读写分离</h3> |
| 389 | +</div> |
| 390 | +</div> |
| 391 | +</div> |
| 392 | +<div id="postamble" class="status"> |
| 393 | +<p class="author">Author: 王月阳</p> |
| 394 | +<p class="date">Created: 2017-09-18 周一 23:19</p> |
| 395 | +<p class="creator"><a href="http://www.gnu.org/software/emacs/">Emacs</a> 24.5.1 (<a href="http://orgmode.org">Org</a> mode 8.2.10)</p> |
| 396 | +<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p> |
| 397 | +</div> |
| 398 | +</body> |
| 399 | +</html> |
0 commit comments