- 浏览: 228586 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
annyliyear:
找到的ExtJS实现多选下拉框3个代码 -
yinboxian:
源码太乱了
JXTA中使用JxtaServerPipe和JxtaBiDiPipe实现双向可靠的通信 -
yinboxian:
我的peers第一次执行时可以得到正确的结果,以后就不行了。不 ...
JXTA中基于管道监听方式通信 -
cuizhenfu#gmail.com:
http://www.cnblogs.com/cuizhf
JXTA中使用JxtaServerPipe和JxtaBiDiPipe实现双向可靠的通信 -
luxing44530:
请问, jsp页面如果在 META-INF 中, 改怎么访问? ...
Servlet3.0 新特性之模块化实践
要把多个任务分派给Java的多个线程去执行,这其中就会有一个任务列表指派到线程的策略思考:已知:1. 一个待执行的任务列表,2. 指定要启动的线程数;问题是:每个线程实际要执行哪些任务。
使用Java多线程实现这种任务分发的策略是:任务列表连续按线程数分段,先保证每线程平均能分配到的任务数,余下的任务从前至后依次附加到线程中--只是数量上,实际每个线程执行的任务都还是连续的。如果出现那种僧多(线程) 粥(任务) 少的情况,实际启动的线程数就等于任务数。这里只实现了每个线程各扫自家门前雪,动作快的完成后眼见别的线程再累都是爱莫能助。
实现及演示代码如下:由三个类实现,写在了一个 Java 文件中:TaskDistributor 为任务分发器,Task 为待执行的任务,WorkThread 为自定的工作线程。代码中运用了命令模式,如若能配以监听器,用上观察者模式来控制 UI 显示就更绝妙不过了,就能实现像下载中的区块着色跳跃的动感了,在此定义下一步的着眼点了。
可以实现任务的多线程分配,为分布式计算做基础
代码中有较为详细的注释,看这些注释和执行结果就很容易理解的。main() 是测试方法
package com.unmi.common;
import java.util.ArrayList;
import java.util.List;
/**
* 指派任务列表给线程的分发器
*/
public class TaskDistributor {
/**
* 测试方法
* @param args
*/
public static void main(String[] args) {
//初始化要执行的任务列表
List taskList = new ArrayList();
for (int i = 0; i < 108; i++) {
taskList.add(new Task(i));
}
//设定要启动的工作线程数为 5 个
int threadCount = 5;
List[] taskListPerThread = distributeTasks(taskList, threadCount);
System.out.println("实际要启动的工作线程数:"+taskListPerThread.length);
for (int i = 0; i < taskListPerThread.length; i++) {
Thread workThread = new WorkThread(taskListPerThread[i],i);
workThread.start(); } }
/**
* 把 List 中的任务分配给每个线程,先平均分配,剩于的依次附加给前面的线程
* 返回的数组有多少个元素 (List) 就表明将启动多少个工作线程
* @param taskList 待分派的任务列表
* @param threadCount 线程数
* @return 列表的数组,每个元素中存有该线程要执行的任务列表
*/
public static List[] distributeTasks(List taskList, int threadCount) {
// 每个线程至少要执行的任务数,假如不为零则表示每个线程都会分配到任务
int minTaskCount = taskList.size() / threadCount;
// 平均分配后还剩下的任务数,不为零则还有任务依个附加到前面的线程中
int remainTaskCount = taskList.size() % threadCount;
// 实际要启动的线程数,如果工作线程比任务还多
// 自然只需要启动与任务相同个数的工作线程,一对一的执行
// 毕竟不打算实现了线程池,所以用不着预先初始化好休眠的线程
int actualThreadCount = minTaskCount > 0 ? threadCount : remainTaskCount;
// 要启动的线程数组,以及每个线程要执行的任务列表
List[] taskListPerThread = new List[actualThreadCount];
int taskIndex = 0;
//平均分配后多余任务,每附加给一个线程后的剩余数,重新声明与 remainTaskCount
//相同的变量,不然会在执行中改变 remainTaskCount 原有值,产生麻烦
int remainIndces = remainTaskCount;
for (int i = 0; i < taskListPerThread.length; i++) {
taskListPerThread[i] = new ArrayList();
// 如果大于零,线程要分配到基本的任务
if (minTaskCount > 0) {
for (int j = taskIndex; j < minTaskCount + taskIndex; j++) {
taskListPerThread[i].add(taskList.get(j));
}
taskIndex += minTaskCount;
}
// 假如还有剩下的,则补一个到这个线程中
if (remainIndces > 0) {
taskListPerThread[i].add(taskList.get(taskIndex++));
remainIndces--;
}
}
// 打印任务的分配情况
for (int i = 0; i < taskListPerThread.length; i++) {
System.out.println("线程 " + i + " 的任务数:" + taskListPerThread[i].size() + " 区间[" + taskListPerThread[i].get(0).getTaskId() + "," + taskListPerThread[i].get(taskListPerThread[i].size() - 1).getTaskId() + "]");
}
return taskListPerThread;
}
}
/**
* 要执行的任务,可在执行时改变它的某个状态或调用它的某个操作
* 例如任务有三个状态,就绪,运行,完成,默认为就绪态
* 要进一步完善,可为 Task 加上状态变迁的监听器,因之决定UI的显示
*/
class Task {
public static final int READY = 0;
public static final int RUNNING = 1;
public static final int FINISHED = 2;
private int status; //声明一个任务的自有业务含义的变量,用于标识任务
private int taskId; //任务的初始化方法
public Task(int taskId){
this.status = READY;
this.taskId = taskId;
}
/**
* 执行任务
*/
public void execute() {
// 设置状态为运行中
setStatus(Task.RUNNING);
System.out.println("当前线程 ID 是:" + Thread.currentThread().getName() +" | 任务 ID 是:"+this.taskId);
// 附加一个延时
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 执行完成,改状态为完成
setStatus(FINISHED);
}
public void setStatus(int status) {
this.status = status;
}
public int getTaskId() {
return taskId;
}
}
/**
* 自定义的工作线程,持有分派给它执行的任务列表
*/
class WorkThread extends Thread {
//本线程待执行的任务列表,你也可以指为任务索引的起始值
private List taskList = null;
private int threadId;
/**
* 构造工作线程,为其指派任务列表,及命名线程 ID
* @param taskList 欲执行的任务列表
* @param threadId 线程 ID
*/
public WorkThread(List taskList,int threadId) {
this.taskList = taskList;
this.threadId = threadId; } /** * 执行被指派的所有任务 */
public void run() { for (Task task : taskList) { task.execute(); } } }
发表评论
-
内存池的实现原理
2024-04-07 16:20 01、内存池的概念 内存池是一种用于管理内存分配和释放的技术 ... -
Java NIO - Buffer
2024-04-06 18:06 0Java NIO中的Buffer用于和NIO通道进行交互。数 ... -
Java NIO - Socket通道
2024-04-06 01:11 01、新的Socket通道类可 ... -
Maven打成Zip包
2013-11-13 17:06 10611如果当前项目是使用Maven管理,并且需要打成Zip,按平 ... -
sigar开发注意点
2013-11-13 16:50 3094<dependency> < ... -
asfasdfasdfasdf
2012-10-11 21:48 0request.setCharacterEncoding(&q ... -
java.lang.NoClassDefFoundError: javax/persistence/EntityListener
2010-12-30 16:08 0正确答案是:添加hibernate3.5.*/lib/jpa/ ... -
共享spket和axis教程
2010-11-26 22:04 1153共享spket和axis教程 -
Try/catch/finally的另一种写法
2010-05-28 21:26 1649从学习Java以来,只是知道try/catch/finally ... -
如何在Eclipse安装反编译工具jad插件
2010-05-01 00:59 32511,将net.sf.jadclipse_3.3.0.jar拷贝 ... -
二分搜寻法(搜寻原则的代表)
2010-04-15 15:42 835如果搜寻的数列已经有排序,应该尽量利用它们已排序的特性,以减少 ... -
如何提高自己的Java编程水平
2010-04-09 00:21 116311. 扎实的基础。数 ... -
剑客vs刀客 Java vs .NET之飘逸的Java
2010-03-28 11:42 679剑,一把好剑,重三两三分,轻如蝉翼,千年寒冰所铸,剑身咖啡色, ... -
Log4j基本使用方法
2010-03-28 10:57 771Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输 ... -
Java GUI 三态导航树
2010-03-27 19:48 18821 通过Java Swing实现的一个三态树组件,包括选择、去 ... -
Directory Chooser API
2010-03-26 23:42 867Java swing provides File choose ... -
Java操作Word文档封装类
2010-03-25 18:46 1465基于开源项目jacob的基础上,封装了操作Word常用的方法和 ... -
[Java]双缓冲技术
2010-03-25 00:59 4351我们很多用Java中的g.drawImage()方法导入图像时 ... -
Java String转Date
2010-03-06 08:37 899Date date = new Date();String s ... -
利用Transaction ProxyFactoryBean 生成事务代理
2010-03-06 08:36 1257采用这种方式的配置时,其配置文件的增加非常快,每个bean 有 ...
相关推荐
但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 从逻辑角度来看,多线程的意义在于一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的...
线程(thread),有时被称为轻量级进程...一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。
一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。每一个程序都至少有一个线程,若程序...
但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程的执行控制。 一个线程可以创建和撤销另一个线程,同一进程中的多个线程之间可以并发执行。 第8页 Java程序设计案例教程-第8章-多线程编程...
多核多线程技术。线程与进程有很多类似的性质,因此人们习惯上也称线程为轻量级进程(lightweight process, LWP) ,也是CPU 调度和分派的基本单元;...果进程有多个控制线程,那么它就能同时执行多个任务。
一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪、阻塞和运行三种基本状态。每一个程序都至少有一个线程,若程序...
一个进程中可以包含一个或多个线程,一个线程就是程序内部的一条执行线索。 在单线程中,程序代码按调用顺序依次往下执行,不能实现两段程序代码同时交替运行的效果。如果一个程序中要实现两段程序代码同时交替运行...
程序、进程和线程 程序是一组指令的有序集合,也可以将其通俗地理解为若干行代码。...一个进程可以包含多个线程,每个线程执行自己的任务,同一个进程中的所有线程共享该进程中的资源,如内存空间、文件句柄等。
线程是程序执行时的最小单位,即CPU调度和分派的基本单位,一个进程可以由多个线程组成,同一个进程中的多个线程之间共享此进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下...
同一个进程中的多个线程之间可以并发执行 在Java中,每次程序运行至少启动2个线程:一个是main线程,一个是垃圾收gc集线程。每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM实际上就是在操作...
二是由于对称多处理机(SMP)出现,可以满足多个运行单位,而多个进程并行开销过大。 因此在80年代,出现了能独立运行的基本单位——线程(Threads)。 线程,有时被称为轻量级进程(Lightweight Process,LWP),...
一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。 线程也有就绪、阻塞和运行三种基本状态。 线程和进程的区别在于,子进程和父进程有不同的代码和数据空间,而多个线程则共享数据空间
在单个程序中同时运行多个线程完成不同的工作,称为多线程 对于IO密集型的程序来说,多线程可以利用读IO的时间去做其他事【IO并不占用CPU,这就好像A买个一份外卖,他只需要等着送过来然后敲A家的门就行了】; 而...
Dispatcher对象:在WPF中,每个线程都有一个Dispatcher对象,它负责在该线程上分派事件和处理操作。 MVVM模式:MVVM模式是一种设计模式,特别适用于WPF应用程序。 以上是一些常见的C#跨类跨线程访问UI线程控件的技术...
然而,传统推测多线程方法所使用 的“沿控制流将串行程序划分为多个线程”的做法并不适合不同数据结构上的操作在控制流中相互交错的情况,因 为如果沿控制流将程序线性地划分为多个线程,则同一个数据结构上的操作将...
一、什么是线程?... 当多个任务可以并行执行时,可以为每个任务启动一个线程。 三、线程的创建 使用pthread_create函数。 #include int pthread_create (pthread_t *__restrict __newthread,//新创建
多线程的相关概念——————————————————————————–1.进程:是操作系统结构的基础;...一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的
同一个进程中的多个线程之间可以并发执行.相对进程而言,线程是一个更加接近于执行体的概念,它可以与同进程中的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。在串行程序基础上引入线程和进程是为