<div id="article_details" class="details">
<div class="article_title">
<span class="ico ico_type_Original"></span>
<h1>
<span class="link_title"><a href="/u012385190/article/details/53302239">
java多线程并发及线程池
</a>
</span>
</h1>
</div>
<div class="article_manage clearfix">
<div class="article_l">
<span class="link_categories">
标签:
<a href="http://www.csdn.net/tag/%e5%a4%9a%e7%ba%bf%e7%a8%8b" target="_blank" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">多线程</a><a href="http://www.csdn.net/tag/java" target="_blank" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">java</a>
</span>
</div>
<div class="article_r">
<span class="link_postdate">2016-11-23 17:04</span>
<span class="link_view" title="阅读次数">1537人阅读</span>
<span class="link_comments" title="评论次数"> <a href="#comments" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_pinglun'])">评论</a>(0)</span>
<span class="link_collect tracking-ad" data-mod="popu_171"> <a href="javascript:void(0);" οnclick="javascript:collectArticle('java%e5%a4%9a%e7%ba%bf%e7%a8%8b%e5%b9%b6%e5%8f%91%e5%8f%8a%e7%ba%bf%e7%a8%8b%e6%b1%a0','53302239');return false;" title="收藏" target="_blank">收藏</a></span>
<span class="link_report"> <a href="#report" οnclick="javascript:report(53302239,2);return false;" title="举报">举报</a></span>
</div>
</div> <style type="text/css">
.embody{
padding:10px 10px 10px;
margin:0 -20px;
border-bottom:solid 1px #ededed;
}
.embody_b{
margin:0 ;
padding:10px 0;
}
.embody .embody_t,.embody .embody_c{
display: inline-block;
margin-right:10px;
}
.embody_t{
font-size: 12px;
color:#999;
}
.embody_c{
font-size: 12px;
}
.embody_c img,.embody_c em{
display: inline-block;
vertical-align: middle;
}
.embody_c img{
width:30px;
height:30px;
}
.embody_c em{
margin: 0 20px 0 10px;
color:#333;
font-style: normal;
}
</style>
<script type="text/javascript">
$(function () {
try
{
var lib = eval("("+$("#lib").attr("value")+")");
var html = "";
if (lib.err == 0) {
$.each(lib.data, function (i) {
var obj = lib.data[i];
//html += '<img src="' + obj.logo + '"/>' + obj.name + " ";
html += ' <a href="' + obj.url + '" target="_blank">';
html += ' <img src="' + obj.logo + '">';
html += ' <em><b>' + obj.name + '</b></em>';
html += ' </a>';
});
if (html != "") {
setTimeout(function () {
$("#lib").html(html);
$("#embody").show();
}, 100);
}
}
} catch (err)
{ }
});
</script>
<div class="category clearfix">
<div class="category_l">
<img src="http://static.blog.csdn.net/images/category_icon.jpg">
<span>分类:</span>
</div>
<div class="category_r">
<label οnclick="GetCategoryArticles('6536400','u012385190','top','53302239');">
<span οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_fenlei']);">线程<em>(1)</em></span>
<img class="arrow-down" src="http://static.blog.csdn.net/images/arrow_triangle _down.jpg" style="display:inline;">
<img class="arrow-up" src="http://static.blog.csdn.net/images/arrow_triangle_up.jpg" style="display:none;">
<div class="subItem">
<div class="subItem_t"><a href="http://blog.csdn.net/u012385190/article/category/6536400" target="_blank">作者同类文章</a><i class="J_close">X</i></div>
<ul class="subItem_l" id="top_6536400">
</ul>
</div>
</label>
</div>
</div>
<div class="bog_copyright">
<p class="copyright_p">版权声明:本文为博主原创文章,转载请指明文章出处!</p>
</div>
<div style="clear:both"></div><div style="border:solid 1px #ccc; background:#eee; float:left; min-width:200px;padding:4px 10px;"><p style="text-align:right;margin:0;"><span style="float:left;">目录<a href="#" title="系统根据文章中H1到H6标签自动生成文章目录">(?)</a></span><a href="#" οnclick="javascript:return openct(this);" title="展开">[+]</a></p><ol style="display:none;margin-left:14px;padding-left:14px;line-height:160%;"><li><a href="#t0">线程的常用创建方式</a></li><li><a href="#t1">多线程并发</a></li><li><a href="#t2">线程池</a></li></ol></div><div style="clear:both"></div><div id="article_content" class="article_content tracking-ad" data-mod="popu_307" data-dsm="post">
<div class="markdown_views"><h2 id="线程的常用创建方式"><a name="t0" target="_blank"></a>线程的常用创建方式</h2>
<p>1、继承Thread类创建线程类</p>
<pre class="prettyprint" name="code"><code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FirstThreadTest</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Thread</span> {</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>(){
System.out.println(<span class="hljs-string">"这里是线程的执行方法"</span>);
}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String[] args) {
<span class="hljs-comment">//获得线程</span>
FirstThreadTest thread = <span class="hljs-keyword">new</span> FirstThreadTest();
System.out.println(<span class="hljs-string">"线程名称为:"</span>+thread.getName());
<span class="hljs-comment">//启动线程</span>
thread.start();
System.out.println(<span class="hljs-string">"main方法也是一个线程:"</span>+Thread.currentThread().getName());
}
}</code><ul class="pre-numbering" style="opacity: 0;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul><div class="save_code tracking-ad" data-mod="popu_249" style="display: none;"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li></ul></pre>
<p>执行结果:</p>
<pre class="prettyprint" name="code"><code class="hljs mathematica has-numbering">线程名称为:<span class="hljs-keyword">Thread</span>-<span class="hljs-number">0</span>
main方法也是一个线程:main
这里是线程的执行方法</code><ul class="pre-numbering" style="opacity: 0;"><li>1</li><li>2</li><li>3</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul></pre>
<p>2、通过Runnable接口创建线程类 <br>
(1)定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体; <br>
(2)创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象; <br>
(3)调用线程对象的start()方法来启动该线程。</p>
<pre class="prettyprint" name="code"><code class="hljs java has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RunnableThreadTest</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Runnable</span> {</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
System.out.println(<span class="hljs-string">"这里是线程方法"</span>);
System.out.println(<span class="hljs-string">"线程名为:"</span> + Thread.currentThread().getName());
}
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String[] args) {
System.out.println(<span class="hljs-string">"main方法线程:"</span> + Thread.currentThread().getName());
RunnableThreadTest rtt = <span class="hljs-keyword">new</span> RunnableThreadTest();
<span class="hljs-keyword">new</span> Thread(rtt, <span class="hljs-string">"新线程1"</span>).start();
<span class="hljs-keyword">new</span> Thread(rtt, <span class="hljs-string">"新线程2"</span>).start();
}
}</code><ul class="pre-numbering" style="opacity: 0;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul></pre>
<p>执行结果</p>
<pre class="prettyprint" name="code"><code class="hljs has-numbering">main方法线程:main
这里是线程方法
线程名为:新线程1
这里是线程方法
线程名为:新线程2</code><ul class="pre-numbering" style="opacity: 0;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul></pre>
<p>两种线程创建的具体区别:<a href="http://www.cnblogs.com/whgw/archive/2011/10/03/2198506.html" target="_blank">http://www.cnblogs.com/whgw/archive/2011/10/03/2198506.html</a>(扩展性和资源共享性)</p>
<h2 id="多线程并发"><a name="t1" target="_blank"></a>多线程并发</h2>
<p>多线程并发出现问题主要涉及到两个方面:多线程共享数据同步问题和数据因并发产生不一致问题;</p>
<p>1、多线程共享数据同步问题 <br>
如下代码:</p>
<pre class="prettyprint" name="code"><code class="hljs java has-numbering"><span class="hljs-javadoc">/**
* 两个工人一起搬砖
*/</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Banzhuan</span> {</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String[] args) {
<span class="hljs-comment">// 一个工厂</span>
Factory factory = <span class="hljs-keyword">new</span> Factory();
<span class="hljs-javadoc">/**
* p1线程和p2线程都是由factory这个实例创建的
* 那么p1调用外部类的getZhuanTou()方法就相当于调用的是factory这个实例的getZhuanTou(),同样的,p2调用的也是factory这个实例的getZhuanTou().
* 那么这里就出现了两个线程同时访问factory的getZhuanTou()方法。
* 而factory的getZhuanTou()方法又对zhuanTou这个属性进行了zhuanTou--操作。
* 换句话说,两个线程同时访问了factory的数据zhuanTou.这时候就可能产生线程安全问题。
*/</span>
<span class="hljs-comment">// 同一个工厂的两个工人</span>
Person p1 = factory.getPerson();
Person p2 = factory.getPerson();
p1.start();
p2.start();
}
}
<span class="hljs-comment">// 工厂</span>
class Factory {
<span class="hljs-keyword">int</span> zhuanTou = <span class="hljs-number">20</span>;<span class="hljs-comment">// 一共20块砖头</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getZhuanTou</span>() {
<span class="hljs-keyword">if</span> (zhuanTou == <span class="hljs-number">0</span>) {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(Thread.currentThread().getName()+ <span class="hljs-string">",没有砖头搬了!"</span>);
}
Thread.yield();
<span class="hljs-keyword">return</span> zhuanTou--;
}
<span class="hljs-comment">// 工人</span>
class Person extends Thread {
<span class="hljs-comment">// 不停的搬砖</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
<span class="hljs-keyword">while</span> (<span class="hljs-keyword">true</span>) {
<span class="hljs-comment">// 获取线程名(工人名) 及 剩下砖头数</span>
System.out.println(getName() + <span class="hljs-string">"搬了第"</span> + getZhuanTou() + <span class="hljs-string">"块砖头"</span>);
<span class="hljs-comment">// 当线程的run方法中出现了异常,且我们没有 解决,那么该线程终止并死亡。但不会影响 当前进程中的其他线程。</span>
Thread.yield();
}
}
}
<span class="hljs-comment">// 获取工人</span>
<span class="hljs-keyword">public</span> Person <span class="hljs-title">getPerson</span>() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Person();
}
}</code><ul class="pre-numbering" style="opacity: 0;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li><li>34</li><li>35</li><li>36</li><li>37</li><li>38</li><li>39</li><li>40</li><li>41</li><li>42</li><li>43</li><li>44</li><li>45</li><li>46</li><li>47</li><li>48</li><li>49</li><li>50</li><li>51</li><li>52</li><li>53</li></ul></pre>
<p><strong>多次</strong>运行结果: <br>
<img src="https://img-blog.csdn.net/20161123140324842" alt="这里写图片描述" title=""></p>
<p><strong>这里并不是每次都会出错,要多运行几次,就会可能碰到多种错误</strong>,比如搬到了同一块砖,比如少搬一块砖,比如搬完到了0然后还有继续搬…… <br>
原因是:比如现在还剩15块砖头,工人p1搬第15块砖头的时候正拿到手上,但是还没有登记减少一块砖头(即还没有运行zhuanTou–),这个时候工人p2也去拿砖,然后登记的时候一看还剩15块砖头,实际呢只剩14块了…… <br>
<strong>解决方法:</strong> <br>
synchronized:当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。 <br>
所以将getZhuanTou()方法改成如下就可以了</p>
<pre class="prettyprint" name="code"><code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getZhuanTou</span>() {
synchronized (<span class="hljs-keyword">this</span>) {
<span class="hljs-keyword">if</span> (zhuanTou == <span class="hljs-number">0</span>) {
<span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> RuntimeException(Thread.currentThread().getName()+<span class="hljs-string">",没有砖头搬了!"</span>);
}
Thread.<span class="hljs-keyword">yield</span>();
<span class="hljs-keyword">return</span> zhuanTou--;
}
}</code><ul class="pre-numbering" style="opacity: 0;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul></pre>
<p>为啥不将这个关键词锁在方法那呢?尽量将锁在范围最小的地方,这样运行的效率更快。</p>
<p>2、数据因并发产生不一致问题 <br>
参考:<a href="https://my.oschina.net/clopopo/blog/149368" target="_blank">https://my.oschina.net/clopopo/blog/149368</a></p>
<p><strong>ThreadLocal</strong>:为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象。</p>
<p>首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问不到的。各个线程中访问的是不同的对象; </p>
<p>另外,说ThreadLocal使得各线程能够保持各自独立的一个对象,并不是通过ThreadLocal.set()来实现的,而是通过每个线程中的new 对象的操作来创建的对象,每个线程创建一个,不是什么对象的拷贝或副本。</p>
<p>再次,注意每一个线程都保存一个对象的时候(非基本类型数据)应该是new一个新对象而不是引用一个对象,如下:</p>
<pre class="prettyprint" name="code"><code class="hljs java has-numbering"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> ThreadLocal<Index> local = <span class="hljs-keyword">new</span> ThreadLocal<Index>() {
<span class="hljs-annotation">@Override</span>
<span class="hljs-keyword">protected</span> Index <span class="hljs-title">initialValue</span>() {
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Index(); <span class="hljs-comment">//注意这里</span>
}
};</code><ul class="pre-numbering" style="opacity: 0;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul></pre>
<p>案例代码:</p>
<pre class="prettyprint" name="code"><code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> ThreadLocalTest {
<span class="hljs-comment">//创建一个Integer型的线程本地变量</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> final ThreadLocal<Integer> local = <span class="hljs-keyword">new</span> ThreadLocal<Integer>() {
@Override
<span class="hljs-keyword">protected</span> Integer <span class="hljs-title">initialValue</span>() {
<span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
}
};
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String[] args) throws InterruptedException {
Thread[] threads = <span class="hljs-keyword">new</span> Thread[<span class="hljs-number">5</span>];
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> j = <span class="hljs-number">0</span>; j < <span class="hljs-number">5</span>; j++) {
threads[j] = <span class="hljs-keyword">new</span> Thread(<span class="hljs-keyword">new</span> Runnable() {
@Override
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
<span class="hljs-comment">//获取当前线程的本地变量,然后累加5次</span>
<span class="hljs-keyword">int</span> num = local.<span class="hljs-keyword">get</span>();
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i < <span class="hljs-number">5</span>; i++) {
num++;
}
<span class="hljs-comment">//重新设置累加后的本地变量</span>
local.<span class="hljs-keyword">set</span>(num);
System.<span class="hljs-keyword">out</span>.println(Thread.currentThread().getName() + <span class="hljs-string">" : "</span>+ local.<span class="hljs-keyword">get</span>());
}
}, <span class="hljs-string">"Thread-"</span> + j);
}
<span class="hljs-keyword">for</span> (Thread thread : threads) {
thread.start();
}
}
}</code><ul class="pre-numbering" style="opacity: 0;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li><li>31</li><li>32</li><li>33</li></ul></pre>
<p>运行结果: <br>
Thread-0 : 5 <br>
Thread-4 : 5 <br>
Thread-2 : 5 <br>
Thread-1 : 5 <br>
Thread-3 : 5</p>
<pre class="prettyprint" name="code"><code class="hljs brainfuck has-numbering"><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-literal">-</span></code><ul class="pre-numbering" style="opacity: 0;"><li>1</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li></ul></pre>
<p>3、总结: <br>
ThreadLocal和Synchonized都用于解决多线程并发访问。但是ThreadLocal与synchronized有本质的区别: <br>
1、synchronized关键字主要解决多线程共享数据同步问题,ThreadLocal使用场合主要解决多线程中数据因并发产生不一致问题; <br>
2、synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享; <br>
synchronized和ThreadLocal比较:<a href="http://blog.csdn.net/huyongl1989/article/details/8088841" target="_blank">http://blog.csdn.net/huyongl1989/article/details/8088841</a></p>
<h2 id="线程池"><a name="t2" target="_blank"></a>线程池</h2>
<p>当有许多请求需要去处理的时候,如果只是单独的一个人去处理,可想而知那会让后面在排队的人等多久,这样就需要线程池,有请求过来了就到线程池里面取出一条线程去处理它,处理完成就把它收回到线程池里面,然而自己实现 一个功能强大的线程池也并非易事,在java1.5之后专门提供了线程池的类库。</p>
<p><a href="http://lib.csdn.net/base/java" class="replace_word" title="Java 知识库" target="_blank" style="color:#df3434; font-weight:bold;">Java</a>通过Executors接口提供四种线程池,分别为: <br>
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程; <br>
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待; <br>
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行; <br>
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行; <br>
下面简单看一下newFixedThreadPool这种线程池:</p>
<pre class="prettyprint" name="code"><code class="hljs cs has-numbering"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> ThreadPoolExecutorTest {
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String[] args) {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(<span class="hljs-number">3</span>);
<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++) {
final <span class="hljs-keyword">int</span> index = i;
fixedThreadPool.submit(<span class="hljs-keyword">new</span> Runnable() {
<span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span>() {
<span class="hljs-keyword">try</span> {
System.<span class="hljs-keyword">out</span>.println(Thread.currentThread().getName()+<span class="hljs-string">"---->"</span>+index);
Thread.sleep(<span class="hljs-number">2000</span>);
} <span class="hljs-keyword">catch</span> (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}</code><ul class="pre-numbering" style="opacity: 0;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li></ul><div class="save_code tracking-ad" data-mod="popu_249"><a href="javascript:;" target="_blank"><img src="http://static.blog.csdn.net/images/save_snippets.png"></a></div><ul class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li></ul></pre>
<p>运行: <br>
pool-1-thread-1—->0 <br>
pool-1-thread-3—->2 <br>
pool-1-thread-2—->1 <br>
pool-1-thread-3—->3 <br>
pool-1-thread-2—->5 <br>
pool-1-thread-1—->4 <br>
pool-1-thread-3—->6 <br>
pool-1-thread-1—->8 <br>
pool-1-thread-2—->7 <br>
pool-1-thread-3—->9</p>
<p>因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。 <br>
fixedThreadPool.submit(Runnable task)或者execute方法会调用线程的run方法;</p>
<p>线程池参考地址:<a href="http://blog.csdn.net/u012385190/article/details/52486393" target="_blank">http://blog.csdn.net/u012385190/article/details/52486393</a></p></div>
<script type="text/javascript">
$(function () {
$('pre.prettyprint code').each(function () {
var lines = $(this).text().split('\n').length;
var $numbering = $('<ul></ul>').addClass('pre-numbering').hide();
$(this).addClass('has-numbering').parent().append($numbering);
for (i = 1; i <= lines; i++) {
$numbering.append($('<li></li>').text(i));
};
$numbering.fadeIn(1700);
});
});
</script>
</div>
<!-- Baidu Button BEGIN -->
<div class="bdsharebuttonbox tracking-ad bdshare-button-style0-16" style="float: right;" data-mod="popu_172" data-bd-bind="1498814705862">
<a href="#" class="bds_more" data-cmd="more" style="background-position:0 0 !important; background-image: url(http://bdimg.share.baidu.com/static/api/img/share/icons_0_16.png?v=d754dcc0.png) !important" target="_blank"></a>
<a href="#" class="bds_qzone" data-cmd="qzone" title="分享到QQ空间" style="background-position:0 -52px !important" target="_blank"></a>
<a href="#" class="bds_tsina" data-cmd="tsina" title="分享到新浪微博" style="background-position:0 -104px !important" target="_blank"></a>
<a href="#" class="bds_tqq" data-cmd="tqq" title="分享到腾讯微博" style="background-position:0 -260px !important" target="_blank"></a>
<a href="#" class="bds_renren" data-cmd="renren" title="分享到人人网" style="background-position:0 -208px !important" target="_blank"></a>
<a href="#" class="bds_weixin" data-cmd="weixin" title="分享到微信" style="background-position:0 -1612px !important" target="_blank"></a>
</div>
<script>window._bd_share_config = { "common": { "bdSnsKey": {}, "bdText": "", "bdMini": "1", "bdMiniList": false, "bdPic": "", "bdStyle": "0", "bdSize": "16" }, "share": {} }; with (document) 0[(getElementsByTagName('head')[0] || body).appendChild(createElement('script')).src = 'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' + ~(-new Date() / 36e5)];</script>
<!-- Baidu Button END -->
<!--172.16.140.13-->
<!-- Baidu Button BEGIN -->
<script type="text/javascript" id="bdshare_js" data="type=tools&uid=1536434" src="http://bdimg.share.baidu.com/static/js/bds_s_v2.js?cdnversion=416338"></script>
<script type="text/javascript">
document.getElementById("bdshell_js").src = "http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=" + Math.ceil(new Date()/3600000)
</script>
<!-- Baidu Button END -->
<div id="digg" articleid="53302239">
<dl id="btnDigg" class="digg digg_enable" οnclick="btndigga();">
<dt>顶</dt>
<dd>1</dd>
</dl>
<dl id="btnBury" class="digg digg_enable" οnclick="btnburya();">
<dt>踩</dt>
<dd>0</dd>
</dl>
</div>
<div class="tracking-ad" data-mod="popu_222"><a href="javascript:void(0);" target="_blank"> </a> </div>
<div class="tracking-ad" data-mod="popu_223"> <a href="javascript:void(0);" target="_blank"> </a></div>
<script type="text/javascript">
function btndigga() {
$(".tracking-ad[data-mod='popu_222'] a").click();
}
function btnburya() {
$(".tracking-ad[data-mod='popu_223'] a").click();
}
</script>
<ul class="article_next_prev">
<li class="prev_article"><span οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_shangyipian']);location.href='http://blog.csdn.net/u012385190/article/details/53198345';">上一篇</span><a href="http://blog.csdn.net/u012385190/article/details/53198345" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_shangyipian'])">mybatis相关介绍</a></li>
<li class="next_article"><span οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_xiayipian']);location.href='http://blog.csdn.net/u012385190/article/details/53331432';">下一篇</span><a href="http://blog.csdn.net/u012385190/article/details/53331432" οnclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_xiayipian'])">Spring quartz定时任务Service注入问题</a></li>
</ul>
<div style="clear:both; height:10px;"></div>
<div class="similar_article">
<h4></h4>
<div class="similar_c" style="margin:20px 0px 0px 0px">
<div class="similar_c_t">
相关文章推荐
</div>
<div class="similar_wrap tracking-ad" data-mod="popu_36">
<ul class="similar_list fl">
<li>
<em>•</em>
<a href="http://blog.csdn.net/cqkxboy168/article/details/9026205" title="并发 并行 同步 异步 多线程的区别" strategy="BlogCommendFromBaidu" target="_blank">并发 并行 同步 异步 多线程的区别</a>
</li>
<li>
<em>•</em>
<a href="http://blog.csdn.net/escaflone/article/details/10418651" title="Java 多线程 并发编程" strategy="BlogCommendFromBaidu" target="_blank">Java 多线程 并发编程</a>
</li>
<li>
<em>•</em>
<a href="http://blog.csdn.net/he90227/article/details/47252793" title="多线程与并发知识点总结" strategy="BlogCommendFromBaidu" target="_blank">多线程与并发知识点总结</a>
</li>
<li>
<em>•</em>
<a href="http://blog.csdn.net/luozhonghua2014/article/details/44170867" title="多线程并发快速处理数据" strategy="BlogCommendFromBaidu" target="_blank">多线程并发快速处理数据</a>
</li>
<li>
<em>•</em>
<a href="http://blog.csdn.net/qq_33290787/article/details/51790605" title="多线程 ---并发与并行概念总结" strategy="BlogCommendFromBaidu" target="_blank">多线程 ---并发与并行概念总结</a>
</li>
</ul>
<ul class="similar_list fr">
<li>
<em>•</em>
<a href="http://blog.csdn.net/z69183787/article/details/52910299" title="线程与进程的区别以及对多线程并发的理解" strategy="BlogCommendFromBaidu" target="_blank">线程与进程的区别以及对多线程并发的理解</a>
</li>
<li>
<em>•</em>
<a href="http://blog.csdn.net/eson_15/article/details/51553597" title="【java并发】线程并发库的使用" strategy="BlogCommendFromBaidu" target="_blank">【java并发】线程并发库的使用</a>
</li>
<li>
<em>•</em>
<a href="http://blog.csdn.net/zhoudaxia/article/details/24294583" title="Java并发与多线程教程(1)" strategy="BlogCommendFromBaidu" target="_blank">Java并发与多线程教程(1)</a>
</li>
<li>
<em>•</em>
<a href="http://blog.csdn.net/cselmu9/article/details/51366946" title="高并发下线程安全的单例模式(最全最经典)" strategy="BlogCommendFromBaidu" target="_blank">高并发下线程安全的单例模式(最全最经典)</a>
</li>
<li>
<em>•</em>
<a href="http://ahua186186.iteye.com/blog/2109498" title="总结--线程池拒绝策略+线程中断处理+多线程并发任务处理" strategy="BlogCommendFromCsdn" target="_blank">总结--线程池拒绝策略+线程中断处理+多线程并发任务处理</a>
</li>
</ul>
</div>
</div>
</div>
</div>
java多线程并发及线程池
最新推荐文章于 2024-08-18 23:25:39 发布