• 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
  • 相关阅读:
    linux命令df中df -h和df -i的区别
    linux系统df和du命令的区别
    Linux type命令的用法
    《DNS的正向反向解析》RHEL6
    《DNS服务缓存的建立》RHEL6
    《服务器的追踪与审计》RHEL6
    《LDAP服务器和客户端的加密认证》RHEL6——第二篇 运维工程师必考
    《ISCSI集中存储》RHEL6——CE
    《LDAP服务器的配置与客户端的测试》RHEL6——第一篇 运维工程师必考
    《RHEL6硬盘的分区和swap分区管理》——硬盘分区的大总结
  • 原文地址:https://www.cnblogs.com/jpfss/p/11143063.html
Copyright © 2020-2023  润新知