java多线程并发及线程池

来源:互联网 发布:程序员到架构师 编辑:程序博客网 时间:2024/05/25 18:12
<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" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_tag']);">多线程</a><a href="http://www.csdn.net/tag/java" target="_blank" onclick="_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" onclick="_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);" onclick="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" onclick="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 onclick="GetCategoryArticles('6536400','u012385190','top','53302239');">                        <span onclick="_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="#" onclick="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="http://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" onclick="btndigga();">                                <dt>顶</dt>                <dd>1</dd>            </dl>                                     <dl id="btnBury" class="digg digg_enable" onclick="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 onclick="_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" onclick="_gaq.push(['_trackEvent','function', 'onclick', 'blog_articles_shangyipian'])">mybatis相关介绍</a></li>                <li class="next_article"><span onclick="_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" onclick="_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>

阅读全文
0 0
原创粉丝点击