Java创建线程池两种不同方法的比较

用java做抓取的时候免不了要用到多线程的了,因为要同时抓取多个网站或一条线程抓取一个网站的话实在太慢,而且有时一条线程抓取同一个网站的话也比较浪费CPU资源。要用到多线程的等方面,也就免不了对线程的控制或用到线程池。   我在做我们现在的那一个抓取框架的时候,就曾经用过java.util.concurrent.ExecutorService作为线程池,关于ExecutorService的使用代码大概如下:

java.util.concurrent.Executors类的API提供大量创建连接池的静态方法:

1.固定大小的线程池:

package BackStage;  

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

  public class JavaThreadPool {
     public static void main(String[] args) {
         // 创建一个可重用固定线程数的线程池
          ExecutorService pool = Executors.newFixedThreadPool(2);
         // 创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
         Thread t1 = new MyThread();
         Thread t2 = new MyThread();
         Thread t3 = new MyThread();
         Thread t4 = new MyThread();
         Thread t5 = new MyThread();
         // 将线程放入池中进行执行
         pool.execute(t1);
         pool.execute(t2);
         pool.execute(t3);
         pool.execute(t4);
         pool.execute(t5);
         // 关闭线程池
         pool.shutdown();
     }
 }  

 class MyThread extends Thread {
     @Override
     public void run() {
         System.out.println(Thread.currentThread().getName() + "正在执行。。。");
     }
 }

后来发现ExecutorService的功能没有想像中的那么好,而且最多只是提供一个线程的容器而然,所以后来我用改用了java.lang.ThreadGroup,ThreadGroup有很多优势,最重要的一点就是它可以对线程进行遍历,知道那些线程已经运行完毕,还有那些线程在运行。关于ThreadGroup的使用代码如下:

<span style="font-size:18px;"><span style="background-color: rgb(255, 255, 255);">class MyThread extends Thread {
   boolean stopped;  

   MyThread(ThreadGroup tg, String name) {
     super(tg, name);
     stopped = false;
   }  

   public void run() {
     System.out.println(Thread.currentThread().getName() + " starting.");
     try {
       for (int i = 1; i < 1000; i++) {
         System.out.print(".");
         Thread.sleep(250);
         synchronized (this) {
           if (stopped)
             break;
         }
       }
     } catch (Exception exc) {
       System.out.println(Thread.currentThread().getName() + " interrupted.");
     }
     System.out.println(Thread.currentThread().getName() + " exiting.");
   }  

   synchronized void myStop() {
     stopped = true;
   }
 }  

 public class Main {
   public static void main(String args[]) throws Exception {
     ThreadGroup tg = new ThreadGroup("My Group");  

     MyThread thrd = new MyThread(tg, "MyThread #1");
     MyThread thrd2 = new MyThread(tg, "MyThread #2");
     MyThread thrd3 = new MyThread(tg, "MyThread #3");  

     thrd.start();
     thrd2.start();
     thrd3.start();  

     Thread.sleep(1000);  

     System.out.println(tg.activeCount() + " threads in thread group.");  

     Thread thrds[] = new Thread[tg.activeCount()];
     tg.enumerate(thrds);
     for (Thread t : thrds)
       System.out.println(t.getName());  

     thrd.myStop();  

     Thread.sleep(1000);  

     System.out.println(tg.activeCount() + " threads in tg.");
     tg.interrupt();
   }
 }</span></span>

由以上的代码可以看出:ThreadGroup比ExecutorService多以下几个优势

1.ThreadGroup可以遍历线程,知道那些线程已经运行完毕,那些还在运行

2.可以通过ThreadGroup.activeCount知道有多少线程从而可以控制插入的线程数

本文来自博客园:http://www.cnblogs.com/yy2011/archive/2011/05/05/2037564.html

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索线程
, execute方法未用到
, new
, thread
, java 线程池
, system
, 多线程抓取
, ExecutorService
, println
, Java线程池框架
, 抓取Thread
, Java抓取
Executors
java 创建线程池、java如何创建线程池、java创建一个线程池、java创建和使用线程池、java怎么创建线程池,以便于您获取更多的相关知识。

时间: 2024-11-08 19:09:35

Java创建线程池两种不同方法的比较的相关文章

Java创建线程的两种方式_java

前言 多线程是我们开发过程中经常遇到的,也是必不可少需要掌握的.当我们知道需要进行多线程开发时首先需要知道的自然是如何实现多线程,也就是我们应该如何创建线程. 在Java中创建线程和创建普通的类的对象操作是一样的,我们可以通过两种方式来创建线程: 1.继承Thread类,并重写run()方法. 2.实现Runnable接口,并实现run()方法. 方法一:继承Thread类 代码非常简单 首先重载一个构造函数,以便我们可以给线程命名. 重写run()方法. 这里我们先让线程输出线程名+start

JAVA创建线程池

线程池的作用: 线程池作用就是限制系统中执行线程的数量. 根据系统的环境情况,可以自动或 手动设置线程数量,达到运行的最佳效果:少了浪费了系统资源,多了造成系统拥挤效率不高.用线程池控制 线程数量,其他线程排队等候.一个任务执行完毕,再从队列的中取最前面的任务开始执行.若队列中没有等 待进程,线程池的这一资源处于等待.当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开 始运行了:否则进入等待队列. 为什么要用线程池: 减少了创建和销毁线程的次数,每个工作 线程都可以被重复利用,可执行

java创建线程的三种方式及其对比

Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行体. (2)创建Thread子类的实例,即创建了线程对象. (3)调用线程对象的start()方法来启动该线程. package com.thread; public class FirstThreadTest extends Thread{ int i = 0; //重写run方法,run方法的方

Java创建多线程的两种方式对比_java

采用继承Thead类实现多线程: 优势:编写简单,如果需要访问当前线程,只需使用this即可,无需使用Thead.currentThread()方法. 劣势:因为这种线程类已经继承了Thead类,所以不能再继承其它类. 示例代码: 复制代码 代码如下:  package org.frzh.thread;    public class FirstThread extends Thread{      private int i;           //重写run方法,run方法的方法体就是线程

java多线程总结一:线程的两种创建方式及优劣比较

http://blog.csdn.net/touch_2011/article/details/6891026 1.通过实现Runnable接口线程创建 (1).定义一个类实现Runnable接口,重写接口中的run()方法.在run()方法中加入具体的任务代码或处理逻辑. (2).创建Runnable接口实现类的对象. (3).创建一个Thread类的对象,需要封装前面Runnable接口实现类的对象.(接口可以实现多继承) (4).调用Thread对象的start()方法,启动线程 示例代码

创建后台任务的两种代码模式

创建后台任务的两种代码模式 后台任务是每个App都需要的一些行为,毕竟主线程是大爷,拖不起,伤不起,脏活累活都只能在不见天日的后台去做. 最简单的后台任务,可以说是直接开一个线程就可以了,或者说来个Service,再开个线程.但这些并不是官方认证的最佳实践,实际上,Google早就考虑到了这一点,并把这些需求进行了封装,给我们提供了非常好的后台任务解决方案,并在Training上进行了讲解: 官网镇楼: https://developer.android.com/training/best-ba

java中线程池的使用(ThreadPoolExecutor)

一.为什么使用线程池: 1.降低资源消耗.主要指的是降低创建和销毁线程时产生的cpu资源消耗,线程池通过持续工作的线程执行不断分配的新任务,来减少频繁的线程创建与销毁. ##2.提高响应速度.同上 ##3.提高线程的可管理性.线程是稀缺资源,频繁的创建销毁,以及没有控制的大量创建,都会影响系统的稳定性.使用线程池可以统一分配,调优,监控资源. 二.如何创建线程池: new ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long

java实现多线程的两种方式继承Thread类和实现Runnable接口的方法_java

实现方式和继承方式有什么区别呢? *区别: *继承Thread:线程代码存放在Thread子类run方法中 *实现Runnable:线程代码存放在接口的子类的run方法中 *实现方式的好处:避免了单继承的局限性 *在定义线程时,建议使用实现方式,当然如果一个类没有继承父类,那么也可以通过继承Thread类来实现多线程 *注意:Runnable接口没有抛出异常,那么实现它的类只能是try-catch不能throws *Java对多线程的安全问题提供了专业的解决方式就是同步代码块synchroniz

Java使用线程池递归压缩文件夹下面的所有子文件

本文将介绍Java中利用线程池递归的方式压缩文件夹下面的所有子文件,具体方法如下: Gzip单个文件压缩 对于单个文件使用GZip压缩. package date0805.demo1;    import java.io.BufferedInputStream;  import java.io.BufferedOutputStream;  import java.io.File;  import java.io.FileInputStream;  import java.io.FileOutpu