Java工作队列和线程池
背景
最近的需要做一个与设备通信的web项目。当然,我们需要写好与设备之间的通信协议(socket)。大致的时序逻辑时:当用户用浏览器点击页面某一控件后,它就向后台发送一个post请求,后台解析前台发送的参数,然后封装成相应的帧格式,然后与设备进行通信,设备接到指令后,完成相应的功能,然后将数据信息返回给后台服务器,后台服务器将这些返回的数据组织好,一方面返回给前台页面,一方面将数据存储到数据库中。
问题:
1.由于通信设备只允许一个socket与它通信,因此,所有的用户都需要共用一个socket,所以,在某一时刻,不能有2个用户同时使用socket
2.当很多条相同的指令以较短的时间间隔(1s左右)发送到通信设备时,通信设备只响应第一条,其他的不予响应。
解决方案
针对上述问题,我们就会想到通过使用队列和线程池来解决以上问题。我们可以将所有用户的指令依次放入队列中,线程池中只允许一个线程运行,而且线程执行完之后,还可以休眠一段时间,等通信设备反应过来的时候,再依次执行队列中的指令。
队列和线程池演示程序
1.WorkQueue.java
该类实现了队列和线程池,详见如下
/*
* $filename: WorkQueue.java,v $
* $Date: 2013-11-20 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb; import java.util.LinkedList; /*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb
*mail: zhb931706659@126.com
*2013-11-20 Nanjing,njupt,China
*References:http://www.ibm.com/developerworks/java/library/j-jtp0730/index.html
*/
public class WorkQueue
{
private final int nThreads;//同时最多执行的线程个数
private final PoolWorker[] threads;//线程池
private final LinkedList queue;//线程队列 public WorkQueue(int nThreads)
{
this.nThreads = nThreads;
queue = new LinkedList();
threads = new PoolWorker[nThreads]; for (int i=0; i<nThreads; i++) {
threads[i] = new PoolWorker();
threads[i].start();
}
} public void execute(Runnable r) {
synchronized(queue) {
queue.addLast(r);
queue.notify();
}
} private class PoolWorker extends Thread {
public void run() {
Runnable r; while (true) {
synchronized(queue) {
while (queue.isEmpty()) {
try
{
queue.wait();
}
catch (InterruptedException ignored)
{
}
} r = (Runnable) queue.removeFirst();
} // If we don't catch RuntimeException,
// the pool could leak threads
try {
r.run();
}
catch (RuntimeException e) {
// You might want to log something here
e.printStackTrace();
}
}
}
}
}
2.WorkThread.java
这是我们的工作线程,在这个Demo中,工作线程只做一件事:将number的值加1,然后休眠,最后打印一下当前number的值。由于number是静态变量,因此我们就可以模拟一下,工作队列的一个执行情况。
/*
* $filename: WorkThread.java,v $
* $Date: 2013-11-20 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb;
/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb
*mail: zhb931706659@126.com
*2013-11-20 Nanjing,njupt,China
*/
public class WorkThread extends Thread{
public static int number = 0;
@Override
public void run() {
// TODO Auto-generated method stub
try {
number = number + 1;
Thread.sleep(100);
System.out.println("number = "+number);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
3.测试案例1
我们的线程池只允许一个线程同时执行,这样的结果是:打印number的值是从1-10顺序打印
/*
* $filename: TestMain.java,v $
* $Date: 2013-11-20 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb; import java.util.ArrayList;
import java.util.List;
/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb
*mail: zhb931706659@126.com
*2013-11-20 Nanjing,njupt,China
*/
public class TestMain { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
WorkQueue workQueue = new WorkQueue(1);//只允许同时运行1个线程
for (int i = 0; i < 10; i++) {
WorkThread wThread = new WorkThread();
workQueue.execute(wThread);
}
} }
运行结果是:
number = 1
number = 2
number = 3
number = 4
number = 5
number = 6
number = 7
number = 8
number = 9
number = 10
4.测试案例2
线程池中允许同时最多有5个线程一起执行
/*
* $filename: TestMain.java,v $
* $Date: 2013-11-20 $
* Copyright (C) ZhengHaibo, Inc. All rights reserved.
* This software is Made by Zhenghaibo.
*/
package edu.njupt.zhb; import java.util.ArrayList;
import java.util.List;
/*
*@author: ZhengHaibo
*web: http://blog.csdn.net/nuptboyzhb
*mail: zhb931706659@126.com
*2013-11-20 Nanjing,njupt,China
*/
public class TestMain { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
WorkQueue wQueue = new WorkQueue(5);//允许同时运行5个线程
for (int i = 0; i < 10; i++) {
WorkThread wThread = new WorkThread();
wQueue.execute(wThread);
}
} }
运行结果是:
number = 5
number = 5
number = 5
number = 5
number = 5
number = 10
number = 10
number = 10
number = 10
number = 10
在某些场合中,如果能够承受100个线程同时运行,那么我们就将workqueue线程池的大小设成100,当线程超过100时,就将线程放入队列queue中,等有一些线程执行结束后,依次执行队列中的线程,一直执行到对列为空时,线程池中的100个线程都在等待新的任务加入。
未经允许不得用于商业目的
Java工作队列和线程池的更多相关文章
- java并发包&线程池原理分析&锁的深度化
java并发包&线程池原理分析&锁的深度化 并发包 同步容器类 Vector与ArrayList区别 1.ArrayList是最常用的List实现类,内部是通过数组实现的, ...
- JAVA多线程(三) 线程池和锁的深度化
github演示代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-servic ...
- Java并发包——线程池
Java并发包——线程池 摘要:本文主要学习了Java并发包中的线程池. 部分内容来自以下博客: https://www.cnblogs.com/dolphin0520/p/3932921.html ...
- Java学习笔记 线程池使用及详解
有点笨,参考了好几篇大佬们写的文章才整理出来的笔记.... 字面意思上解释,线程池就是装有线程的池,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程 ...
- Java原理领悟-线程池(Executor)
线程池全面解析 什么是线程池? 很简单,简单看名字就知道是装有线程的池子,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程的复用. 线程池的好处 我 ...
- 《Java并发编程的艺术》 第9章 Java中的线程池
第9章 Java中的线程池 在开发过程中,合理地使用线程池能带来3个好处: 降低资源消耗.通过重复利用已创建的线程 降低线程创建和销毁造成的消耗. 提高响应速度.当任务到达时,任务可以不需要等到线程创 ...
- 浅析Java中的线程池
Java中的线程池 几乎所有需要异步或并发执行任务的程序都可以使用线程池,开发过程中合理使用线程池能够带来以下三个好处: 降低资源消耗 提高响应速度 提高线程的可管理性 1. 线程池的实现原理 当我们 ...
- Java多线程与线程池技术
一.序言 Java多线程编程线程池被广泛使用,甚至成为了标配. 线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线程与销毁线程也属于重操作,为了提高效率,先提前创建好一批 ...
- Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor
介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...
随机推荐
- 向OC类中添加默认的协议实现(ProtocolKit)
以forkingdog的PorotocolKit举例 举例 ProtocolKit Protocol extension for Objective-C Usage Your protocol: @p ...
- GPUImage 滤镜头文件
#import "GLProgram.h" // Base classes #import "GPUImageOpenGLESContext.h" #impor ...
- iBatis系列一
XML iBatis可以使用xml来作为参数输入以及结果返回:这个功能的优势在于某些特定的场景:还有可以通过DOM方式来作为参数传递:但是这个方式应用的比较少,如果服务器是xml服务器可以采用这种方式 ...
- 图片Base64编码 简单使用
图片在线转换Base64,图片编码base64 http://tool.css-js.com/base64.html HTML5 + js <input type="file" ...
- iOS面试题16719-b
1. 反转二叉树,不用递归 /*** Definition for a binary tree node.* public class TreeNode {* int val;* Tr ...
- C++引用作为函数的参数
引用也可以作为一个函数的参数,如:我们定义交换两个数的函数swap,将函数的参数定义成引用的形式: void swap(int &p1, int &p2) //此处函数的形参都是引用 ...
- csu 10月 月赛 J 题
Description CSU又到了一年中评奖学金的时候了……各大学霸都或多或少地拿到了各种奖学金(你们自己看着办吧). 在这里,评奖学金有个很奇怪的规矩——每个同学得到的奖学金数一定满足相邻的两个非 ...
- laravel 框架学习资料
demo:http://forumsarchive.laravel.io/viewtopic.php?id=3536 使用Laravel和Angular创建一个单页的评论应用 http://devel ...
- 一起啃PRML - 1.1 Example: Polynomial Curve Fitting 多项式曲线拟合
一起啃PRML - 1.1 Example: Polynomial Curve Fitting @copyright 转载请注明出处 http://www.cnblogs.com/chxer/ 前言: ...
- BZOJ_1565_[NOI2009]_植物大战僵尸_(Tarjan+最大流+最大权闭合图)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1565 n*m的矩阵,可以种植植物,僵尸从图的右边进入吃植物.前面的植物可以保护后面的植物,还有 ...