使用future机制和对象锁实现SynchronizedExecutor

欢迎查看Eetal的第九篇博客–使用future机制和对象锁实现SynchronizedExecutor

future

future代表一个任务的预执行结果,通过get方法获取执行结果

1
2
3
public interface Future<V> {
V get() throws Exception;
}

callable

callable代表一个要执行的任务,执行方法call,执行完成返回一个值

1
2
3
public interface Callable<V> {
V call() throws Exception;
}

executor

executor为执行器,通过执行器来执行任务并得到预执行结果对象future

1
2
3
public interface Executor<V> {
Future<V> execute(Callable<V> callable);
}

SynchronizedExecutor

使用synchronized关键字实现的执行器

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
public class SynchronizedExecutor<V> implements Executor<V> {

static class ExecutorThread<V> extends Thread{
public Object lock;
public V result;
public Callable<V> task;
public Exception e;
public boolean isDone = false;
public ExecutorThread(Callable<V> task,Object lock) {
this.lock = lock;
this.task = task;
}
@Override
public void run() {
try {
result = task.call();
} catch (Exception e) {
this.e = e;
}finally {
synchronized (lock) {
//需持有锁才能调用notify
this.isDone = true;
lock.notifyAll();
//此处的加锁只是为了获得锁
}
}

}

}

@Override
public Future<V> execute(Callable<V> callable) {
Object lock = new Object();
ExecutorThread<V> thread = new ExecutorThread<V>(callable,lock);
thread.start();
Future<V> future = new Future<V>() {

@Override
public V get() throws Exception {
synchronized (lock) {
//通过锁机制,使得未完成时,get方法陷入等待队列,让出cpu给别的线程,异步完成时再唤醒
//需持有锁才能调用wait
while(!thread.isDone) {
lock.wait();
}
if(thread.e != null) {
throw thread.e;
}
return thread.result;
}
}

};

return future;
}

}

总结

优点:通过多线程执行并立即返回一个Future对象,而不等待任务,使得源线程继续执行,
只有当源线程需要多线程执行结果,调用其get方法时,通过创建执行线程时创建的对象锁来阻塞线程直到任务执行完成
当执行过程中如果有抛出异常,则先捕获该异常,在调用get执行结果时再抛出

请移步

个人主页: yangyitao.top