用Stack实现对多线程的管理范例
多线程就是并发技术,当线程数量超过一定数量时,系统响应就会变慢,所以就必须对线程数量进行控制,那么采用哪种控制方法呢?采用Stack类模仿堆栈,之所以说是模仿,就是因为Stack类毕竟不是真实的堆栈,push和pop操作也并非是真正的入栈和出栈操作!程序思路是创建一个线程池管理类ThreadPool类,这个类的作用是用于创建指定数量的工作线程并压入栈中,此外还负责唤醒线程进行工作(方法是performedWork(Object data)),还有一个将执行完任务的线程重新压入栈中的方法push(),在线程池类内部有一个嵌套的工作线程WorkerThread类,这个类就是具体负责执行任务的工作线程,但是任务的具体执行者是由接口Worker或继承了该接口的实际类完成的。这里有几个关键点,一个数据对象,在创建了线程但还没有传入data对象时线程是一直处于wait()阻塞状态中。只有通过wake(Object data)方法进行唤醒并工作。
例程如下:
package thread.test;
import java.util.Stack;
public class StackThread {
static class WorkProcess implements Worker{
@Override
public void run(Object data) {
System.out.println(data);
}
}
public static void main(String[] args) throws Exception {
WorkProcess wp=new WorkProcess();
ThreadPool tp = new ThreadPool(wp.getClass(),10);
for(int i=0;i<11;i++) //输出的顺序是没有先后的,第十一个线程为额外线程
tp.performedWork("function#"+i);
}
}
class ThreadPool{
class WorkerThread extends Thread{
private Object data;
private Worker worker;
//工作线程需要两个参数,标识符和工作接口,还需要一个数据用于运行run(Object data)方法,在得到data对象之前,线程一直处于阻塞状态
public WorkerThread(String idoilt,Worker worker){
super(idoilt);
this.worker=worker;
data=null;
}
synchronized public void wake(Object data){
this.data=data;
this.notify();
}
@Override
synchronized public void run(){
boolean stop=false;
while(!stop){
if(data==null){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(data!=null){ //下面这两句话可能不会同时输出,即线程会在输出第一句话之后切换到另外一个线程
System.out.println(this.getName());
worker.run(data);
}
data=null;
stop=push(this);
}
}
}
@SuppressWarnings("rawtypes")
private Stack _waiting; //被所有线程所共享的对象,所以必须同步,用于存放所有的工作线程
@SuppressWarnings("rawtypes")
private Class _workerClass;
int _max;
@SuppressWarnings({ "unchecked", "rawtypes" })
public ThreadPool(Class workerClass,int max)throws Exception{
_workerClass=workerClass;
_max=max;
_waiting =new Stack();
Worker wo;
WorkerThread wt;
for(int i=0;i<_max;i++){//创建一定数量的工作线程
wo=(Worker)_workerClass.newInstance(); //产生一个新的实例,均是继承于Worker接口。
wt=new WorkerThread("worker#"+i,wo);
wt.start();//请网友思考一下为什么这里要启动方法,而不在performedWork方法中启动呢?但实际确实必须在这里启动
_waiting.push(wt);
}
}
//执行工作线程方法,传入data对象唤醒线程进行工作
public void performedWork(Object data)throws InstantiationException, IllegalAccessException{
WorkerThread w= null;
synchronized(_waiting){
if(_waiting.empty()){
w=new WorkerThread("addtional thread",
(Worker)_workerClass.newInstance());
w.start();
}
else {
w=(WorkerThread)_waiting.pop();
//w.start(); //这条语句是错的,会引发一个IllegalThreadStateException异常,具体原因我也不清楚,你想清楚了,可以告诉我
//在这里启动可能就会导致wake方法失去意义,因为唤醒线程之前必须处于阻塞状态,也就是必须启动线程!在这里启动并不会立即启动
//线程,而是会继续往下执行wake方法,由于线程未启动就唤醒就会出错!
}
w.wake(data);
}
}
@SuppressWarnings("unchecked")
public boolean push(WorkerThread obj){
boolean isPOP=false;
synchronized(_waiting){
if(_waiting.size()<_max){
_waiting.push(obj);
isPOP=true;
}
}
return isPOP;
}
}
interface Worker {
public void run(Object data);
}
这辆直升机是九江红鹰制造的,确实非常不错,看起来真酷!
用Stack实现对多线程的管理范例的更多相关文章
- C++ 11 多线程--线程管理
说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...
- JAVA多线程读写文件范例
在写之前先声明,本文是基于之前在博客园网站上检索到的一份JAVA多线程读写文件的示例,我在写自己的程序时是在那位作者写的基础上做了改良,但已不记得原文的地址.如果有知情者,烦请帖出地址,我在此文上加入 ...
- (转)C++ 11 多线程--线程管理
说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...
- Java多线程事务管理
今天要讨论的是"Java实现多线程单条数据事务管理",在此之前,顺便回顾一下实现多线程的几种方式 实现多线程的三种方式 一.继承Thread类 第一种方法是继承Thread类,重写 ...
- [C++] Win32 API 的多线程Timer管理Trick - 利用PostThreadMessage
有时候我们需要在程序里定时地完成一些任务, 比如5秒后发送, 10秒后弹窗之类的操作. 这就需要一个类似于定时器的组件. 这个组件在windows.h里被称为Timer. 设置一个Timer 第一步当 ...
- JVM的stack和heap,JVM内存模型,垃圾回收策略,分代收集,增量收集
(转自:http://my.oschina.net/u/436879/blog/85478) 在JVM中,内存分为两个部分,Stack(栈)和Heap(堆),这里,我们从JVM的内存管理原理的角度来认 ...
- [转]C#学习笔记15——C#多线程编程
一.基本概念进程:当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的.线程:线程是程序中的一个执行流,每个线程都有自己的专有寄存 ...
- Linux堆内存管理深入分析(上)
Linux堆内存管理深入分析(上半部) 作者:走位@阿里聚安全 0 前言 近年来,漏洞挖掘越来越火,各种漏洞挖掘.利用的分析文章层出不穷.从大方向来看,主要有基于栈溢出的漏洞利用和基于堆溢出的漏洞 ...
- [.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(三) 利用多线程提高程序性能(下)
[.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(二) 利用多线程提高程序性能(下) 本节导读: 上节说了线程同步中使用线程锁和线程通知的方式来处理资源共享问题,这 ...
随机推荐
- T-Sql中的pivot和unpivot
写在前面 今天休息,抽空了解下pivot和unpivot,记得老师讲行转列的时候,貌似提到过,不过他说的最多的就是“这个你们私下可以自己学,很简单的...”,简单你咋不讲呢,不吐槽他了,还是好好整理下 ...
- 交换机Trunk端口配置
本文为转发,简单明了,我喜欢. Trunk端口的配置步骤如下: 一 组网需求: 1.SwitchA与SwitchB用trunk互连,相同VLAN的PC之间可以互访,不同VLAN的PC之间禁止互访: 2 ...
- JQuery - 提交表单
[JavaScript] JQuery异步提交表单与文件上传 Jquery.form.js是一个可以异步提交表单及上传文件的插件. 文档地址:http://jquery.malsup.com/form ...
- 如何将一个Jsp网站打包发布(发布为War文件)
链接地址:http://blog.csdn.net/luohuijun619/article/details/4867131 版权声明:本文为博主原创文章,未经博主允许不得转载. 网站做完后,并不是直 ...
- Mac删除废纸篓中的单一文件和文件夹
http://www.macappbox.com/tips/159/ 通过Automator创建教程: 1.打开Automator并选择新建 2.选择服务类型 3.搜索Run Shell Script ...
- jquery插件讲解:轮播(SlidesJs)+验证(Validation)
SlidesJs(轮播支持触屏)——官网(http://slidesjs.com) 1.简介 SlidesJs是基于Jquery(1.7.1+)的响应幻灯片插件.支持键盘,触摸,css3转换. 2.代 ...
- WPF中控件ListView和DataGrid典型属性介绍
ListView GridView View视图 重要属性: public bool AllowsColumnReorder 获取或设置一个值,该值指示 System.Windows.Controls ...
- sql server 实现sleep延时
sql server中实现与C++ 中Sleep类似的功能,可以使用 waitfor delay '00:00:00:10' 表示延时10毫秒
- IP编辑控件(因为封装的是系统自带控件,所以也使用了CreateSubClass,不过为啥要封装CN_COMMAND和CN_NOTIFY不是很明白)
最近需要用一个IP输入控件,网上找了几个,都不符合效果,有些还有一些奇怪的Bug.后来发现原来系统已经提供了IP地址编辑控件,只是系统提供的控件不能设置只读效果.网上找了下资料,封装了一下,自己迂回一 ...
- Windows Phone 8初学者开发的翻译终于过半
从2013年7月19日开始,到2013年12月9日,一共花了143天时间完成了18篇Windows Phone 8初学者开发的翻译,还剩下17篇文章需要翻译,看到了完成的希望! I love Wind ...