可以理解为future就是一个管道,发出请求后有返回的话结果会写回这个管道,后面要自己从里面读
java 多线程是future包住callable任务执行
CompletionService 包装 ExecutorService,ExecutorService提交Runnable返回Future,Future中get(),当然FutureTask可以包装Callable,此时返回就在FutureTask中get()-->阻塞方法
callbale用线程池的时候不需要futureTask包装,用其包装也可,但是在起一个单线程时(没用线程池),此时需要futuretask包装:
FutureTask futureTask = new FutureTask(callable);
Thread thread = new Thread(futureTask);
thread.start();
发起线程的三种方法中:都可以简单的start(),可以放在线程池中
callable是可以返回结果的
thread,runnable不可返回结果
java 中Future是一个未来对象,里面保存这线程处理结果,它像一个提货凭证,拿着它你可以随时去提取结果。在两种情况下,离开Future几乎很难办。一种情况是拆分订单,比如你的应用收到一个批量订单,此时如果要求最快的处理订单,那么需要并发处理,并发的结果如果收集,这个问题如果自己去编程将非常繁琐,此时可以使用CompletionService解决这个问题。CompletionService将Future收集到一个队列里,可以按结果处理完成的先后顺序进队。另外一种情况是,如果你需要并发去查询一些东西(比如爬虫),并发查询只要有一个结果返回,你就认为查询到了,并且结束查询,这时也需要用CompletionService和Future来解决。直接上代码更直观:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CompletionServiceTest {
static int numThread = 100 ;
static ExecutorService executor = Executors.newFixedThreadPool(numThread);
public static void main(String[] args) throws Exception{
//data表示批量任务
int [] data = new int [ 100 ];
for ( int i= 1 ;i< 100000 ;i++){
int idx =i % 100 ;
data[idx] =i;
if (i% 100 == 0 ){
testCompletionService(data);
data = new int [ 100 ];
}
}
}
private static void testCompletionService( int [] data) throws Exception{
CompletionService<Object> ecs = new ExecutorCompletionService<Object>(executor);
for ( int i= 0 ;i<data.length;i++){
final Integer t=data[i];
ecs.submit( new Callable<Object>() {
public Object call() {
try {
Thread.sleep( new Random().nextInt( 1000 ));
} catch (InterruptedException e) {
e.printStackTrace();
}
return t;
}
});
}
//CompletionService会按处理完后顺序返回结果
List<Object> res = new ArrayList<Object>();
for ( int i = 0 ;i<data.length;i++ ){
Future<Object> f = ecs.take();
res.add(f.get());
}
System.out.println(Thread.currentThread().getName()+ ":" +res);
}
private static void testBasicFuture( int [] data) throws Exception{
List<Future<Object>> res = new ArrayList<Future<Object>>();
for ( int i= 0 ;i<data.length;i++){
final Integer t=data[i];
Future<Object> future=executor.submit( new Callable<Object>() {
public Object call() {
return t;
}
});
res.add(future);
}
for ( int i = 0 ;i<res.size();i++ ){
Future<Object> f = res.get(i);
Object rObject =f.get();
System.out.print( ":" +rObject);
}
System.out.println( "LN" );
}
} |
相关推荐
在Java中,有两种主要的实现多线程的方式:通过`Thread`类和通过实现`Runnable`接口。 1. **通过`Thread`类实现多线程** 当我们创建一个`Thread`类的子类时,可以重写`run()`方法来定义线程执行的任务。例如: ``...
这两种方式都可以实现线程的创建和运行,但实现`Runnable`接口更常见,因为它允许你在不干扰类继承结构的情况下复用已有的类。 在实际应用中,你可能还需要考虑线程同步和通信,比如使用`wait()`, `notify()`或`...
创建一个新线程通常有两种方式:继承Thread类并重写run()方法,或者实现Runnable接口并提供run()方法。在run()方法中编写线程执行的代码。 进度条通常由主线程负责显示,而耗时任务则在一个或多个工作线程中执行。...
在Java中,线程有两种创建方式:通过实现`Runnable`接口或继承`Thread`类。实现`Runnable`接口更为灵活,因为它可以避免单继承的限制,同时适用于需要跨平台的情况。 创建线程后,我们可以通过调用`start()`方法...
Java 实现多线程的方式有四种:继承 Thread 类、实现 Runnable 接口、使用 ExecutorService、Callable、Future 实现有返回结果的多线程。启动线程方法 start()和 run()有所区别,start()方法可以表现出多线程的特性...
9. **死锁**:当两个或更多线程相互等待对方释放资源而陷入僵局时,发生死锁。避免死锁需要遵循适当的策略,如避免循环等待,使用死锁预防或死锁避免算法。 10. **线程安全的数据结构**:C++标准库提供了一些线程...
- 创建线程有两种主要方式:继承`Thread`类并重写`run()`方法,或实现`Runnable`接口并提供`run()`方法,然后通过`Thread`构造函数创建线程对象。 - `start()`方法用于启动线程,`run()`方法包含线程执行的主要...
创建Java线程主要有两种方式:继承Thread类和实现Runnable接口。继承Thread类可以直接重写run()方法,而实现Runnable接口则需要提供一个包含业务逻辑的run()方法,并通过构造Thread对象传入该Runnable实例。后者更为...
在Java中,多线程主要通过两种方式实现:继承Thread类和实现Runnable接口。这份"JAVA多线程的PPT和示例"将深入讲解这些内容,帮助开发者更全面地理解和掌握Java多线程技术。 首先,让我们来看看继承Thread类的多...
在Java中,线程是轻量级的,因为它共享进程的内存空间,这使得多线程成为处理大量并发任务的有效方式。创建Java线程有两种主要方法:通过实现`Runnable`接口或继承`Thread`类。`Runnable`通常更灵活,因为它允许线程...
在Java中,实现多线程主要有两种方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当自定义类继承Thread类时,你需要重写它的`run()`方法。创建线程实例后,调用`start()`方法启动线程。`start()`会调用...
Java提供了两种创建线程的方式:继承`Thread`类和实现`Runnable`接口。在`lec22`中,可能会包含这两个方法的示例。继承`Thread`类时,重写`run()`方法,并直接通过`start()`启动新线程。而实现`Runnable`接口则需要...
在编程领域,多线程是实现并发执行任务的关键技术,特别是在资源丰富的现代计算机系统中。本文将深入探讨“简单多线程实例”,旨在帮助你理解并掌握如何在实际项目中运用多线程。 多线程是指在一个程序内同时运行多...
Java中的线程可以通过两种方式创建:继承Thread类或实现Runnable接口。主线程通常由main方法启动,当主线程执行完毕,JVM进程也会结束。 线程的状态转换是多线程编程中的关键概念,包括新建、可运行、运行、阻塞和...
在编程领域,多线程是一种常见的技术,它允许程序同时执行多个不同的任务,极大地提高了程序的效率和响应性。本文将深入探讨多线程的概念、重要性以及如何在实际项目中应用多线程,特别关注Java语言中的多线程实现。...
创建线程有两种主要方式:通过继承`Thread`类或实现`Runnable`接口,然后将实例传递给`Thread`的构造函数。此外,Java还提供了`ExecutorService`和`Future`等高级API,以更灵活和高效的方式来管理线程池和任务执行。...
创建线程主要有两种方式: 1. 继承Thread类:创建一个新的类,该类继承自Thread类,并重写run()方法。然后创建该类的实例并调用start()方法启动线程。 ```java class MyThread extends Thread { public void run() ...
在Java中,创建线程主要有两种方式:继承`Thread`类和实现`Runnable`接口。`concurrent`包提供了一种更高级的线程管理方式,通过`ExecutorService`和`Future`接口,以及`ThreadPoolExecutor`等实现类,我们可以更好...
总结起来,"lotus domino 多线程搜索多数据库内容"是一种利用Java多线程和Lotus Domino API进行高效搜索的方法。通过创建`Callable`任务类和使用`ExecutorService`,我们可以并发地搜索多个数据库,显著提高了搜索...