java多线程并发及线程池

<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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值