package QQ;

import java.util.LinkedList;

/**
* Created by hu on 2015/11/9.
*/
public class ThreadPool extends ThreadGroup{
//线程池是否关闭
private boolean isClosed=false;
//表示工作队列
private LinkedList<Runnable> workQueue;
//表示线程池ID
private static int threadPoolId;
//表示工作线程ID
private int threadId; public ThreadPool(String name) {
super(name);
}
/**
* poolSize指定线程池中工作线程的数目
* */
public ThreadPool(int poolSize){
this("ThreadPool-"+(threadPoolId++));
setDaemon(true);
//创建工作队列
workQueue=new LinkedList<Runnable>();
for(int i=0;i<poolSize;i++){
//创建并启动工作线程
new WorkThread().start();
}
}
/**
* 向工作队列中加入一个新任务,由工作线程去执行该任务
* */
public synchronized void execute(Runnable task){
//线程池被关闭则抛出异常
if(isClosed){
throw new IllegalStateException();
}
if(task!=null){
//将任务添加到工作队列中去
workQueue.add(task);
//唤醒正在getTask()方法中等待任务的工作线程
notify();
}
}
/**
* 从工作队列中取出一个任务,工作线程会调用此方法
* */
protected synchronized Runnable getTask() throws InterruptedException {
while (workQueue.size()==0){
if(isClosed)
return null;
//如果工作队列中没有任务,就等待任务
wait();
}
//取出队列中的第一个任务
return workQueue.removeFirst();
}
/**
* 关闭线程池
* */
public synchronized void close(){
if(isClosed){
isClosed=true;
//清空工作队列
workQueue.clear();
//中断所有工作进程,该方法继承自ThreadGroup类
interrupt();
}
}
/**
* 等待工作进程把所有任务执行完
* */
public void join(){
synchronized (this){
isClosed=true;
//唤醒还在getTask()方法中等待任务的工作进程
notifyAll();
}
Thread[] threads=new Thread[activeCount()];
//enumerate()方法继承自ThreadGroup类,获得线程中当前所有活着的工作线程
int count=enumerate(threads);
for(int i=0;i<count;i++){
try{
//等待工作线程运行结束
threads[i].join();
}catch (InterruptedException ex){
ex.printStackTrace();
}
}
}
private class WorkThread extends Thread{
public WorkThread(){
//加入到当前ThreadPool线程组中
super(ThreadPool.this,"WorkThread-"+(threadPoolId++));
}
public void run(){ while (!isInterrupted()){
Runnable task=null;
try{
//取出任务
task=getTask();
}catch (InterruptedException ex){
ex.printStackTrace();
}
//如果getTask()返回null或者线程执行getTask()时被中断,则结束此线程
if(task==null)
return;
try{
//运行任务,异常在catch块中捕获
task.run();
}catch (Throwable t){
t.printStackTrace();
}
}
}
}
}

  

java网络编程学习笔记(四):线程池的实现的更多相关文章

  1. Java网络编程学习笔记

    Java网络编程,我们先来看下面这一张图: 由图可得:想要进行网络编程,首先是服务器端通过ServerSocket对某一个端口进行监听.通过accept来判断是否有客户端与其相连.若成功连上,则通过r ...

  2. java网络编程学习笔记(一)

    1.进程之间的通信 进程是指运行中的程序,进程的任务就是执行程序中的代码. 存在计算机网络上的两个进程只需要关注它们通信的具体内容,而不需关注消息在网络上传输的具体细节. 2.计算机网络的概念 Int ...

  3. java 网络编程学习笔记

    1.IP地址 IP地址组成:网络号段+主机号段 IP地址分类: A类:第一号段为网络号段+后三段的主机号段 1.0.0.1---127.255.255.254(10.x.x.x是私有地址) 一个网络号 ...

  4. java网络编程学习笔记(二):socket详解

    1.Socket有多种构造方法,大多数构造方法在构造的时候就指定了连接的主机和端口号.当客户端的构造方法与服务器连接的时候,可能需要等待一段时间,因为需要建立连接.默认情况下,Socket的构造方法会 ...

  5. java网络编程学习笔记(三):ServerSocket详解

    1.ServerSocket的构造方法 ServerSocket(); ServerSocket(int port); ServerSocket(int port,int backlog); Serv ...

  6. Java 并发编程——Executor框架和线程池原理

    Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...

  7. Java 并发编程——Executor框架和线程池原理

    Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...

  8. 转 网络编程学习笔记一:Socket编程

    题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...

  9. JUC源码学习笔记5——线程池,FutureTask,Executor框架源码解析

    JUC源码学习笔记5--线程池,FutureTask,Executor框架源码解析 源码基于JDK8 参考了美团技术博客 https://tech.meituan.com/2020/04/02/jav ...

随机推荐

  1. k8s基于RBAC的访问控制(用户授权)

    kubernetes的API Server常用的授权插件有:   Node.ABAC.RBAC.Webhook我们重点说一下RBAC的访问控制逻辑RBAC(Role base access contr ...

  2. crontab -e 和/etc/crontab的区别

    /etc/crontab文件和crontab -e命令区别/etc/crontab文件和crontab -e命令区别 1.格式不同 前者 # For details see man 4 crontab ...

  3. confirm() 方法用于显示一个带有指定消息和 OK 及取消按钮的对话框。系统自带提示

    W3C地址:::::::   http://www.w3school.com.cn/jsref/met_win_confirm.asp http://www.w3school.com.cn/tiy/t ...

  4. django admin模块使用

    BBS之admin组件的使用 1.创建超级管理员 创建超级管理员 一. tools>>>>runmanagepyTask>>>>>createsu ...

  5. [Hdu3652]B-number(数位DP)

    Description 题目大意:求小于n是13的倍数且含有'13'的数的个数. (1 <= n <= 1000000000) Solution 数位DP,题目需要包含13,且被13整除, ...

  6. HDU1272小希的迷宫

    小希的迷宫 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一 ...

  7. RCP 主题切换

    第一步 编写css文件,放到项目目录下 第二步 添加切换主题扩展点 第三步 设置主题   public  void switchTheme(String themeID) {           Bu ...

  8. VS2010Datatable查看器查看超时(Microsoft.VisualStudio.DebuggerVisualizers)

    这个问题由来已久,却一直没有找到原因.大家都知道,VisualStudio的DebuggerVisualizers是一个非常方便的插件,可以帮助我们调试时查看Datatable视图,前阵子突然发现在查 ...

  9. Docker背后的内核知识(二)

    cgroups资源限制 上一节中Docker背后的内核知识(一),我们了解了Docker背后使用的资源隔离技术namespace,通过系统调用构建了一个相对隔离的shell环境,也可以称之为简单的“容 ...

  10. 使用JavaConfig方式-Spring 基础学习

    在Spring的使用中,大量采用xml方式配置类之间的关系太过于繁琐(个人这么认为),而在学习了Spring4后发下使用JavaConfig方式来配置这些关系会更加的简单明了. 测试环境 1. Apa ...