文档章节

Java的多线程任务调度示例

断桥残雪断桥残雪
 断桥残雪断桥残雪
发布于 2015/08/04 09:40
字数 1126
阅读 121
收藏 1

问题背景介绍

首先,问题是如何在一个非常大的数组中找到最小值,当然,传统的方法是一个一个地去找,复杂度为N,若使用主线程进行,则会花费很多时间,若使用多线程进行分段查找,每个线程在一个单独的内核上运行。这样就会快很多。为了便于说明,下面使用两个线程。

Callable接口介绍

java.util.concurrent包中的泛型Callable接口,该接口一般的作用是作为一个计算目标返回,该接口定义了唯一的一个call方法,而call方法可以返回一个泛型的计算结果,如果不能返回,则抛出异常。Callable类似于Runnable接口,都是为了让一个任务的执行放在一个单独的线程中,但是Runnable接口不能返回结果,并且也不会抛出一个受检异常,另外,Callable接口还可以用于lambda表达式中。


java.util.concurrent;  //包名

interface Callable<V>;   //接口

V call();    //子类要实现的方法



任务创建

现在我们来创建一个简单的任务,即计算一组数中的最小值,我们将这个大任务分解成两个小任务,分别计算前一半的最小值和后一半的最小值,然后再求出二者的最小值即可。


package date0803.executor;

import java.util.concurrent.Callable;

/**
 * 通过隐藏细节实现回调
 * Executors可以创建线程池
 * ExecutorService可以根据需要创建线程,可以向ExecutorService提交Callable任务
 * 对于每个Callable任务,会分别得到一个Future
 * Future也是一个接口,提供一个返回任意类型的方法get()
 * Callable接口定义了一个call()方法,它返回一个任意类型的计算结果
 * @author zzw922cn
 *
 */
public class FindMinTask implements Callable<Integer> {
	private int[] data;
	private int start;
	private int end;
	/**
	 * 
	 * @param data 数组
	 * @param start 开始
	 * @param end 末尾
	 */
	public FindMinTask(int[] data, int start, int end) {
		super();
		this.data = data;
		this.start = start;
		this.end = end;
	}
	/**
	 * 实现接口,返回任意类型
	 */
	@Override
	public Integer call() throws Exception {
		int min=Integer.MAX_VALUE;
		for(int i=start;i<end;i++) {
			if(data[i]<min)
				min=data[i];
		}
		return min;
	}
	
	
	
}



任务的提交

ExecutorService接口

这里运用到一个Executor接口,而它有一个子接口ExecutorService,Executor类可以提供方法去管理一个或多个任务的执行进度或结果,返回一个Future泛型接口,Future代表一个异步计算的结果,它提供了一些方法用于检查计算任务是否已经完成,如果没有完成则继续等待其完成,最终取回结果。Future接口只能通过其get()方法取回结果,并且会一直阻塞直到计算已经完成为止,这种做法的优点是你可以按照你需要的顺序来得到你需要的答案。cancel方法可以用于终止执行。ExecutorService接口中定义的submit()方法继承了Executor.execute方法,并且返回一个Future类型,Future再用于取消任务或等待任务完成。另外,Executors提供了ExecutorService对象的工厂创建方法。

程序实例


package date0803.executor;
/**
 * 多线程来提交任务
 * 由线程池创建两个线程进行服务
 */
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class MultiThreadMinFinder {
	public static int max(int[] data) throws InterruptedException,ExecutionException {
		int L=data.length;
		if(L==1) {
			return data[0];
		}else if(L==0) {
			throw new IllegalArgumentException();
		}
		
		FindMinTask task1 = new FindMinTask(data, 0, L/2);
		FindMinTask task2 = new FindMinTask(data, L/2, L);
		
		ExecutorService service=Executors.newFixedThreadPool(2);
		
		Future<Integer> future1 = service.submit(task1);
		Future<Integer> future2 = service.submit(task2);
		
		return Math.min(future1.get(), future2.get());
	}
}



总结

至此,我们就完成了一个任务分成两个小任务的多线程实现。对于合适的硬件和规模很大的输入,程序的速度可以优化一倍以上。注意程序的最后一句

return Math.min(future1.get(), future2.get());
可能会有阻塞,因为它需要等待计算任务已完成,get()方法才能有返回值。一 旦两个任务都已完成,将比较它们的最小值,并返回最小值。

Future是一种很方便的做法,可以启动多个线程来处理一个问题的许多子问题,然后等待它们全部完成后再继续。Executors用来创建ExecutorService对象,这里只使用了两个线程,你完全可以适用多个线程,只要能把大问题适当地分解为若干个小问题即可。

© 著作权归作者所有

断桥残雪断桥残雪
粉丝 53
博文 139
码字总数 94909
作品 0
广州
程序员
私信 提问
Java多线程机制——多线程概述

本文概述 本篇文章将分四块内容对Java中的多线程机制进行介绍: 一. 多线程概述 二. 实现多线程的两种方式 三. 多线程的生命周期 四. 线程调度和控制 一. 线程与进程的概述   线程是依赖于...

Mr_Yanger
2017/11/28
0
0
Active Object 并发模式在 Java 中的应用

本文主要从以下两个方面进行阐述: 使用 C++ 语言,来描述 Active Object 设计模式。 Java 类库对于这样一个典型的模式做了很好的类库层面的封装,因此对于 Java 的开发者来说,很多关于该设计...

红薯
2010/08/08
325
0
cpu个数、核数、线程数、Java多线程关系的理解

一 cpu个数、核数、线程数的关系 cpu个数:是指物理上,也及硬件上的核心数; 核数:是逻辑上的,简单理解为逻辑上模拟出的核心数; 线程数:是同一时刻设备能并行执行的程序个数,线程数=cp...

码代码的小司机
2018/11/06
95
0
JAVA多线程和并发基础面试问答

多线程和并发问题是Java技术面试中面试官比较喜欢问的问题之一。在这里,从面试的角度列出了大部分重要的问题,但是你仍然应该牢固的掌握Java多线程基础知识来对应日后碰到的问题。(校对注:...

LCZ777
2014/05/26
236
0
JAVA多线程和并发基础面试问答

Java多线程面试问题 1. 进程和线程之间有什么不同? 一个进程是一个独立(self contained)的运行环境,它可以被看作一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一...

hanzhankang
2014/01/20
164
0

没有更多内容

加载失败,请刷新页面

加载更多

Jenkins admin 密码忘记解决

一、admin密码未更改情况 1.进入\Jenkins\secrets目录,打开initialAdminPassword文件,复制密码; find / -name initialAdminPassword [root@jenkins jenkins]# cat /var/lib/jenkins/secre......

SuShine
29分钟前
5
0
LiveData原理分析

LiveData原理分析 1 LiveData简介 大部分Android应用会从网络或SQLite数据库存取数据,并根据数据更新界面。为了避免ANR,主线程中不能存取数据。而后台线程中无法更新界面。通常的做法是让后...

tommwq
43分钟前
4
0
Java描述设计模式(20):命令模式

本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景 1、场景描述 智能电脑的品牌越来越多,由此诞生了一款电脑控制的APP,万能遥控器,用户在使用遥控器的时候,可以切换为自家电视的品...

知了一笑
44分钟前
3
0
java---网络编程(上)

1.1网络编程 网络编程指的是编写运行在多个设备计算机的程序,这些计算机通过网络连接起来 java.net包中提供了两种常见的网络协议的支持: TCP:TCP是传输控制层协议的缩写,它保障了两个应用...

Firefly-
48分钟前
15
0
城市搜索插件 city-query

  今天,给大家介绍一个比较简单有用的插件city-query,大家可以从coding上面下载下来。 git clone https://gitee.com/jflsy/city-query.git   引用插件时只需要src文件下的内容就可以了...

芳缘
53分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部