java中线程池的使用方法

1 引入线程池的原因

  由于线程的生命周期中包括创建、就绪、运行、阻塞、销毁阶段,当我们待处理的任务数目较小时,我们可以自己创建几个线程来处理相应的任务,但当有大量的任务时,由于创建、销毁线程需要很大的开销,运用线程池这些问题就大大的缓解了。

2 线程池的使用

  我们只需要运用Executors类给我们提供的静态方法,就可以创建相应的线程池:

  public static ExecutorSevice newSingleThreadExecutor()

  public static ExecutorSevice newFixedThreadPool()

  public static ExecutorSevice  newCachedThreadPool()

  newSingleThreadExecutor返回以个包含单线程的Executor,将多个任务交给此Exector时,这个线程处理完一个任务后接着处理下一个任务,若该线程出现异常,将会有一个新的线程来替代。

  newFixedThreadPool返回一个包含指定数目线程的线程池,如果任务数量多于线程数目,那么没有没有执行的任务必须等待,直到有任务完成为止。

  newCachedThreadPool根据用户的任务数创建相应的线程来处理,该线程池不会对线程数目加以限制,完全依赖于JVM能创建线程的数量,可能引起内存不足。

  我们只需要将待执行的任务放入run方法中即可,将Runnable接口的实现类交给线程池的execute方法,作为它的一个参数,如下所示:

复制代码
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable(){
    public void run(){
       //执行的任务    
  }
}
复制代码

  如果需要给任务传递参数,可以通过创建一个Runnable接口的实现类来完成。 

3 线程池使用的示例

  下面我们通过一个实例来说明线程池的使用方法,该实例模仿子HADOOP中作业初始化过程,也即利用线程池从队列中取出作业并对作业进行初始化,其代码如下:

复制代码
package com.yueliming.ThreadPool;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FixedThreadPool {

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> List&lt;Double&gt;<span style="color: #000000;"> queue;
</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> ExecutorService threadPool;

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> FixedThreadPool() {
    queue </span>= <span style="color: #0000ff;">new</span> ArrayList&lt;Double&gt;<span style="color: #000000;">();
    </span><span style="color: #008000;">//</span><span style="color: #008000;">产生一个 ExecutorService 对象,这个对象带有一个大小为 poolSize 的线程池,若任务数量大于 poolSize ,任务会被放在一个 queue 里顺序执行。 </span>
    threadPool = Executors.newFixedThreadPool(5<span style="color: #000000;">);
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
    FixedThreadPool outer </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> FixedThreadPool();
    FixedThreadPool.Manager inner </span>= outer.<span style="color: #0000ff;">new</span><span style="color: #000000;"> Manager();
    Thread consumer </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> Thread(inner);

    Thread producer </span>= <span style="color: #0000ff;">new</span> Thread() {<span style="color: #008000;">//</span><span style="color: #008000;">用于向queue中放入数据</span>
        <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() {
            </span><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">true</span><span style="color: #000000;">) {
                </span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;"> (queue) {
                    </span><span style="color: #0000ff;">double</span> time =<span style="color: #000000;"> 1d;
                    </span><span style="color: #0000ff;">long</span> startTime =<span style="color: #000000;"> System.currentTimeMillis();
                    </span><span style="color: #0000ff;">if</span> (System.currentTimeMillis() - startTime &gt;=<span style="color: #000000;"> time) {
                        startTime </span>=<span style="color: #000000;"> System.currentTimeMillis();
                        </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">) {
                            queue.add((Math.random() </span>* 10000<span style="color: #000000;">));
                        }
                        queue.notify();
                    }
                }
            }
        }
    };
    consumer.start();</span><span style="color: #008000;">//</span><span style="color: #008000;">启动守护线程,采用线程池来从queue中读取数据</span>

producer.start();
}

</span><span style="color: #0000ff;">class</span> Manager <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Runnable {
    </span><span style="color: #0000ff;">int</span> num = 0<span style="color: #000000;">;
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() {
        </span><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">true</span><span style="color: #000000;">) {
            </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
                </span><span style="color: #0000ff;">synchronized</span><span style="color: #000000;"> (queue) {
                    System.out.println(</span>"队列的长度为:" +<span style="color: #000000;"> queue.size());
                    </span><span style="color: #0000ff;">while</span><span style="color: #000000;"> (queue.isEmpty()) {
                        queue.wait();
                    }
                    </span><span style="color: #0000ff;">double</span> result = queue.remove(0<span style="color: #000000;">);
                    num</span>++<span style="color: #000000;">;
                    System.out.println(</span>"成功从队列中取到数据!" +<span style="color: #000000;"> num);
                    threadPool.execute(</span><span style="color: #0000ff;">new</span><span style="color: #000000;"> ExecutorThread(result));
                }
            } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException t) {
                </span><span style="color: #0000ff;">break</span><span style="color: #000000;">;
            }
        }
        threadPool.shutdown();
    }
}

</span><span style="color: #0000ff;">class</span> ExecutorThread <span style="color: #0000ff;">implements</span><span style="color: #000000;"> Runnable {

    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">double</span><span style="color: #000000;"> value;

    </span><span style="color: #0000ff;">public</span> ExecutorThread(<span style="color: #0000ff;">double</span><span style="color: #000000;"> value) {
        </span><span style="color: #0000ff;">this</span>.value =<span style="color: #000000;"> value;
    }

    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> run() {
        System.out.println(</span>"This is " + Thread.currentThread().getName() + " " +<span style="color: #000000;"> value);
    }
}

}

复制代码

  其中内部类Manager为一个线程负责从队列中获取作业,并交给线程池去处理任务,有一个线程专门将数据放入到队列中,也即每隔1ms向队列中放入10个数据。

原文地址:https://www.cnblogs.com/yueliming/p/3300587.html
posted @ 2019-07-06 16:10  星朝  阅读(5287)  评论(0编辑  收藏  举报