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; } }