java网络编程学习笔记(四):线程池的实现
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网络编程学习笔记(四):线程池的实现的更多相关文章
- Java网络编程学习笔记
Java网络编程,我们先来看下面这一张图: 由图可得:想要进行网络编程,首先是服务器端通过ServerSocket对某一个端口进行监听.通过accept来判断是否有客户端与其相连.若成功连上,则通过r ...
- java网络编程学习笔记(一)
1.进程之间的通信 进程是指运行中的程序,进程的任务就是执行程序中的代码. 存在计算机网络上的两个进程只需要关注它们通信的具体内容,而不需关注消息在网络上传输的具体细节. 2.计算机网络的概念 Int ...
- java 网络编程学习笔记
1.IP地址 IP地址组成:网络号段+主机号段 IP地址分类: A类:第一号段为网络号段+后三段的主机号段 1.0.0.1---127.255.255.254(10.x.x.x是私有地址) 一个网络号 ...
- java网络编程学习笔记(二):socket详解
1.Socket有多种构造方法,大多数构造方法在构造的时候就指定了连接的主机和端口号.当客户端的构造方法与服务器连接的时候,可能需要等待一段时间,因为需要建立连接.默认情况下,Socket的构造方法会 ...
- java网络编程学习笔记(三):ServerSocket详解
1.ServerSocket的构造方法 ServerSocket(); ServerSocket(int port); ServerSocket(int port,int backlog); Serv ...
- Java 并发编程——Executor框架和线程池原理
Eexecutor作为灵活且强大的异步执行框架,其支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务 ...
- Java 并发编程——Executor框架和线程池原理
Java 并发编程系列文章 Java 并发基础——线程安全性 Java 并发编程——Callable+Future+FutureTask java 并发编程——Thread 源码重新学习 java并发 ...
- 转 网络编程学习笔记一:Socket编程
题外话 前几天和朋友聊天,朋友问我怎么最近不写博客了,一个是因为最近在忙着公司使用的一些控件的开发,浏览器兼容性搞死人:但主要是因为这段时间一直在看html5的东西,看到web socket时觉得很有 ...
- JUC源码学习笔记5——线程池,FutureTask,Executor框架源码解析
JUC源码学习笔记5--线程池,FutureTask,Executor框架源码解析 源码基于JDK8 参考了美团技术博客 https://tech.meituan.com/2020/04/02/jav ...
随机推荐
- Shell脚本使用汇总整理——达梦数据库备份脚本
Shell脚本使用汇总整理——达梦数据库备份脚本 Shell脚本使用的基本知识点汇总详情见连接: https://www.cnblogs.com/lsy-blogs/p/9223477.html 脚本 ...
- Android 性能篇 -- 带你领略Android内存泄漏的前世今生
基础了解 什么是内存泄漏? 内存泄漏是当程序不再使用到的内存时,释放内存失败而产生了无用的内存消耗.内存泄漏并不是指物理上的内存消失,这里的内存泄漏是指由程序分配的内存但是由于程序逻辑错误而导致程序失 ...
- js数据结构与算法--递归
递归,函数自己调用自己 return 返回值, 后面的代码不执行 function fn(num){ console.log(num) if(num == 0){ return; } fn(num-1 ...
- Android如何添加多张引导页
摘要:项目需要添加多张引导页,所以在网上搜集了一些资料并整理好. Step1 添加一个GuideActivity. 其实这个引导页无非就是一个Activity,里面有一个ViewPager而已.多张图 ...
- Redis实现之对象(三)
集合对象 集合对象的编码可以是intset或者hashtable,intset编码的集合对象使用整数集合作为底层实现,集合对象包含的所有元素都被保存在整数集合里面.举个栗子,以下代码将创建一个图1-1 ...
- Event log c++ sample.
1. Init regedit. bool InitLog( TCHAR *logName, TCHAR *sourceName, TCHAR *MessageDllName ) { // This ...
- Careercup - Microsoft面试题 - 5672369481842688
2014-05-12 06:27 题目链接 原题: Find the max height of a binary tree. 题目:计算二叉树的最大高度. 解法:最大高度?高度不就是最深的叶子节点到 ...
- windows下SecureCRT无法使用Backspace(删除键)和上下左右键
MongoDB Shell中退格键使用的问题. 利用SecureCRT工具访问linux的时候,在使用MongoDB的交互式shell的时候,退格键(Backspace)无法使用,导致无法修改输入的字 ...
- Leetcode 593.有效正方形
有效正方形 给定二维空间中四点的坐标,返回四点是否可以构造一个正方形. 一个点的坐标(x,y)由一个有两个整数的整数数组表示. 示例: 输入: p1 = [0,0], p2 = [1,1], p3 = ...
- Leetcode 493.翻转对
翻转对 给定一个数组 nums ,如果 i < j 且 nums[i] > 2*nums[j] 我们就将 (i, j) 称作一个重要翻转对. 你需要返回给定数组中的重要翻转对的数量. 示例 ...