import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.List;
public class Concurrency2 {
public static void main(String[] args) {
try {
ThreadPoolExecutor executor = new ThreadPoolExecutor(30, 30, 1,
TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>(9000);
// 发送垃圾邮件, 用户名假设为4位数字
for (int i = 1000; i < 10000; i++) {
futures.add(executor.submit(new FictionalEmailSender(i
+ "@sina.com", "Knock, knock, Neo",
"The Matrix has you...")));
}
// 提交所有的任务后,关闭executor
System.out.println("Starting shutdown...");
executor.shutdown();
// 每秒钟打印执行进度
while (!executor.isTerminated()) {
executor.awaitTermination(1, TimeUnit.SECONDS);
int progress = Math
.round((executor.getCompletedTaskCount() * 100)
/ executor.getTaskCount());
System.out.println(progress + "% done ("
+ executor.getCompletedTaskCount()
+ " emails have been sent).");
}
// 现在所有邮件已发送完, 检查futures, 看成功发送的邮件有多少
int errorCount = 0;
int successCount = 0;
for (Future<Boolean> future : futures) {
if (future.get()) {
successCount++;
} else {
errorCount++;
}
}
System.out.println(successCount
+ " emails were successfully sent, but " + errorCount
+ " failed.");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
class FictionalEmailSender implements Callable<Boolean> {
private String to;
private String subject;
private String body;
public FictionalEmailSender(String to, String subject, String body) {
this.setTo(to);
this.setSubject(subject);
this.setBody(body);
}
@Override
public Boolean call() throws InterruptedException {
// 在0~0.5秒间模拟发送邮件
Thread.sleep(Math.round(Math.random() * 0.5 * 1000));
// 假设我们有80%的几率成功发送邮件
if (Math.random() > 0.2) {
return true;
} else {
return false;
}
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
}