用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的使用代码如下:

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();
}
}

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

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

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

ThreadGroup其实比ExecutorService更好的更多相关文章

  1. Netty5序章之BIO NIO AIO演变

    Netty5序章之BIO NIO AIO演变 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络服务器和客户端程序.Netty简化了网络程序的开发,是很多框架和公司都在使 ...

  2. Netty序章之BIO NIO AIO演变

    Netty序章之BIO NIO AIO演变 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠的网络服务器和客户端程序.Netty简化了网络程序的开发,是很多框架和公司都在使用 ...

  3. JDK的BIO, NIO, AIO

    背景知识点我 1. BIO JDK5之前, JDK的IO模式只有BIO(同步阻塞)问题: 因为阻塞的存在, 需对每个请求开启一个线程. 过多的线程切换影响操作系统性能解决: 使用线程池, 处理不过来的 ...

  4. Java IO------------------BIO(同步阻塞)、NIO1.0(多路复用)、NIO2.0(AIO,非阻塞)

    1. BIO JDK5之前, JDK的IO模式只有BIO(同步阻塞)问题: 因为阻塞的存在, 需对每个请求开启一个线程. 过多的线程切换影响操作系统性能解决: 使用线程池, 处理不过来的放入队列, 再 ...

  5. Java 网络IO编程(BIO、NIO、AIO)

    本概念 BIO编程 传统的BIO编程 代码示例: public class Server { final static int PROT = 8765; public static void main ...

  6. java IO(BIO)、NIO、AIO

    IO 服务端ServerSocket 客户端Socket 缺点每次客户端建立连接都会另外启一个线程处理.读取和发送数据都是阻塞式的. 如果1000个客户端建立连接将会产生1000个线程 Server端 ...

  7. BIO/NIO/AIO的区分(十四)

    BIO:同步阻塞IO(平常说的IO指的是BIO)NIO:同步非阻塞IOAIO:异步非阻塞IO io操作分为两部分,发起io请求,和io数据读写. 阻塞.非阻塞主要是针对线程发起io请求后,是否立即返回 ...

  8. 1.IO的演进

      1.Java IO 演进之路 本文围绕着一下几个问题 1.Java 中 BIO.NIO.AIO 之间的区别及应用场景. 2.阻塞(Block)与非阻塞(Non-Block)区别. 3.同步(Syn ...

  9. Java中的IO、NIO、File、BIO、AIO详解

    java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?         Java中的流分为两种,一种是字节流,另一种是字符流,分别由四个抽象类来表示(每种流包 ...

随机推荐

  1. coffee.js

    ( ) ( ( ) ) ( ( ( ) ) ) ########################## ############################ #################### ...

  2. oracle数据库相关概念介绍

    数据库相关概念介绍: 问题: 数据存储:变量(基本类型,引用类型) 基本类型:少量数据 引用类型:保证数据的完整性 数据源: 声明直接赋值 IO流从硬盘中读取 java在处理数据时,需要从硬盘中读取数 ...

  3. linux -bash . startup.sh Permission denied

    在执行./startup.sh,或者./shutdown.sh的时候,爆出了Permission denied, 其实很简单,就是今天在执行tomcat的时候,用户没有权限,而导致无法执行, 用命令c ...

  4. MSCRM中报表开发二:创建基于FetchXML报表

    1. 获取FetchXML.因为FetchXML难以撰写,所以我们一般都是使用高级查找来生成FetchXML或者通过其他工具来生成.我这里在商机界面通过高级查找制作了一个新的视图,名称为 商机查询,  ...

  5. FreeSSHD login with permission denied

    登录遇到问题: Permission denied, please try again. 解决方法: 在window中使用freesshd开启ssh后,客户端登陆时报 access denied错误 ...

  6. 二层协议--STP协议总结

    生成树协议的技术实现与配置注意点 一.stp协议的用途 二.stp协议的运行机制 三.stp协议规范

  7. 【redis专题(2)】命令语法介绍之string

    REDIS有5大数据结构:string,link,sortedset,sets,hash. 这5个结构我将用5篇文章来记录各自是怎么用的,然后再用一篇文章来说一下各自的应用场景: 更多语法请参考: h ...

  8. [20170623]利用传输表空间恢复数据库2.txt

    [20170623]利用传输表空间恢复数据库2.txt --//继续上午的测试,测试truncate,是否可行,理论讲应该没有问题.我主要的目的测试是否要切换日志.--//参考链接 : http:// ...

  9. [20170824]11G备库启用DRCP连接.txt

    [20170824]11G备库启用DRCP连接.txt --//参考链接:http://blog.itpub.net/267265/viewspace-2099397/blogs.oracle.com ...

  10. 上下文管理器——with语句的实现

    前言 with语句的使用给我们带来了很多的便利,最常用的可能就是关闭一个文件,释放一把锁. 既然with语句这么好用,那我也想让我自己写的代码也能够使用with语句,该怎么实现? 下面具体介绍怎样实现 ...