[Java并发]-03-线程执行器的使用
2014-11-15 08:07
393 查看
3 线程执行器
3.1 Executors工厂
newCachedThreadPool创建ExecutorService 无界线程池,可以进行自动线程回收public static ExecutorService newCachedThreadPool() public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory)
newFixedThreadPool创建ExecutorService 固定大小线程池
public static ExecutorService newFixedThreadPool(int nThreads) public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory)
newSingleThreadExecutor创建ExecutorService单个后台线程
public static ExecutorService newSingleThreadExecutor() public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory)
newScheduledThreadPool创建ScheduledExecutorService
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)
newSingleThreadScheduledExecutor 创建ScheduledExecutorService
public static ScheduledExecutorService newSingleThreadScheduledExecutor() public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory)
ThreadFactory 是提供线程的工厂,执行器 根据工厂创建其中的线程
方法命名上single的不能成为pool 就是称为executor
3.2 ThreadPoolExecutor的构造方法
3.3 使用ThreadPoolExecutorpublic static void main(String[] args) { System.out.println("=========main start"); final ThreadPoolExecutor exec = (ThreadPoolExecutor) Executors .newCachedThreadPool(new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); exec.execute(new Runnable() { @Override public void run() { for (int i = 0; i < 200; i++) { System.out.println("AAA--" + i); } } }); exec.execute(new Runnable() { @Override public void run() { for (int i = 0; i < 200; i++) { System.out.println("BBB--" + i); } } }); exec.execute(new Runnable() { @Override public void run() { for (int i = 0; i < 200; i++) { System.out.println("CCC--" + i); } } }); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } ConcurrencyUtils.printThreadPoolExecutorInfo(exec); System.out.println("=========main end"); }
shutdown()和shutdownNow();都不能终止已经执行的任务,再增加新的任务会向执行器所在线程抛出RejectedExecutionException异常,如未处理该处理异常,执行器所在线程将终止,但是执行器中的任务还将继续执行。
shutdownNow会将排队的任务舍弃,shutdown则会将队列中的任务执行完毕。
public static class Task implements Runnable { private String id; Task(int id) { this.id= "Task-" + id; } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(id + " "+ i); } } } public static void main(String[] args) { System.out.println("=========main start"); final ThreadPoolExecutor exec = (ThreadPoolExecutor) Executors .newFixedThreadPool(5, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); for (int i = 0; i < 10; i++) { exec.execute(new Task(i)); } exec.shutdownNow(); System.out.println(">>>>>>>>>>>>>>>shutdownNow"); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } ConcurrencyUtils.printThreadPoolExecutorInfo(exec); System.out.println("=========main end"); }
...
exec.getPoolSize()=0
exec.getCorePoolSize()=5
exec.getLargestPoolSize()=5
exec.getMaximumPoolSize()=5
exec.getActiveCount()=0
exec.getTaskCount()=5
exec.getCompletedTaskCount()=5
=========main end
如果改成shutdow()
...
exec.getPoolSize()=0
exec.getCorePoolSize()=5
exec.getLargestPoolSize()=5
exec.getMaximumPoolSize()=5
exec.getActiveCount()=0
exec.getTaskCount()=10
exec.getCompletedTaskCount()=10
=========main end
newSingleThreadExecutor只有一个线程的newFixedThreadPool,所有task都在一个线程中执行,也不难看出task是顺序执行的,一个task完成了 才进行下个task。
这个例子可以换成newFixedThreadPool和newCachedThreadPool等,看看线程池中线程分配情况。
public static class Task implements Runnable { private String id; Task(int id) { this.id= "Task-" + id; } @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(id + " " + i + " " + Thread.currentThread().getName() ); } } } public static void main(String[] args) { System.out.println("=========main start"); final ExecutorService exec = Executors .newSingleThreadExecutor(new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); for (int i = 0; i < 10; i++) { exec.execute(new Task(i)); } try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("=========main end"); }
3.4下面看看执行器框架的优势之一-----运行并返回结果
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);
<T> Future<T> submit(Callable<T> task);
Callable接口,call方法中实现任务具体的逻辑,和Runnable的run方法类似,不过Callable是个泛型接口,泛型是返回值的类型。
Future接口 获取Callable返回的结果,并管理他们的状态
继续demo
public static class Task implements Runnable { private String id; Task(int id) { this.id = "Task-" + id; } Task(String id) { this.id = "Task-" + id; } @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(id + " " + i + " " + Thread.currentThread().getName()); } } } public static void main(String[] args) { System.out.println("=========main start"); final ExecutorService exec = Executors.newFixedThreadPool(4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); Callable<Task> callable = new Callable<Task>() { @Override public Task call() throws Exception { System.out.println("call " + " " + Thread.currentThread().getName()); try { TimeUnit.NANOSECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } return new Task("call中的task"); } }; Future<Task> future = exec.submit(callable); do { System.out.println("=========future.isDone() " + future.isDone()); } while (!future.isDone()); Task command = null; if (future.isDone()) { try { command = future.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } exec.execute(command); exec.execute(command); exec.execute(command); exec.execute(command); System.out.println("=========main end"); }
future.isDone()来判断task(Callable的对象)是否执行完成,
其实不需要判断
future.get方法是阻塞的将一直等待call方法执行完成,如果在get方法等待过程中线程中断了则抛出 InterruptedException,如果call方法中抛出了异常则 get方法随之抛出ExecutionException异常
改动一下代码如下
public static void main(String[] args) {
System.out.println("=========main start");
final ExecutorService
4000
exec = Executors.newFixedThreadPool(4, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r);
}
});
Callable<Task> callable = new Callable<Task>() {
@Override
public Task call() throws Exception {
System.out.println("call " + " " + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new Task("call中的task");
}
};
Future<Task> future = exec.submit(callable); // 调用submit返回一个结果,结果是Callable中call()方法返回的
// 是一个Runnble对象
Task command = null;
try {
System.out.println("=========future.get s");
command = future.get();
System.out.println("=========future.get e");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
// 通过future.get()获得返回的结果对象,这个对象是个runnable对象可以 再用执行器执行
exec.execute(command);
exec.execute(command);
exec.execute(command);
exec.execute(command);
System.out.println("=========main end");
}
还可以再改改
用 V get(long timeout, TimeUnit unit) 方法
如果call超过timeout时间还没有完成则抛出TimeoutException,可以用来限制等待时间,不是一直等待下去。
下面代码中 如果超时 command是null;
public static void main(String[] args) { System.out.println("=========main start"); final ExecutorService exec = Executors.newFixedThreadPool(4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); Callable<Task> callable = new Callable<Task>() { @Override public Task call() throws Exception { System.out.println("call " + " " + Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } return new Task("call中的task"); } }; Future<Task> future = exec.submit(callable); Task command = null; try { System.out.println("=========future.get s"); command = future.get(2, TimeUnit.SECONDS); System.out.println("=========future.get e"); } catch (TimeoutException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } if (command != null) { exec.execute(command); exec.execute(command); exec.execute(command); exec.execute(command); } System.out.println("=========main end"); }
3.5 运行多个任务处理第一个结果
下面看看ExecutorService invokeAny 和invokeAll两个方法<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException; <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException; <T> T invokeAny(Collection<? extends Callable<T>> tasks) throws InterruptedException, ExecutionException; <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
有这样一个问题:线程竞赛只用最快的结果
public static class Task implements Callable<String> { private String id; private int workTime; Task(String id, int workTime) { this.id = "Task-" + id; this.workTime = workTime; } @Override public String call() throws Exception { try { TimeUnit.SECONDS.sleep(workTime); } catch (InterruptedException e) { System.out.println(id + " " + "InterruptedException"); } System.out.println(id + " " + Thread.currentThread().getName()); return id; } } public static void main(String[] args) { System.out.println("=========main start"); final ExecutorService exec = Executors.newFixedThreadPool(4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); List<Task> tasks = new ArrayList<Task>(); tasks.add(new Task("2sTask", 2)); tasks.add(new Task("3sTask1", 3)); tasks.add(new Task("3sTask2", 3)); tasks.add(new Task("3sTask3", 3)); tasks.add(new Task("1sTask1", 1)); tasks.add(new Task("1sTask2", 1)); tasks.add(new Task("1sTask3", 1)); tasks.add(new Task("10sTask", 10)); String result = null; try { result = exec.invokeAny(tasks); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("result = " + result); System.out.println("=========main end"); }
=========main start
Task-2sTask Thread-0
result = Task-2sTask
=========main end
Task-3sTask3 InterruptedException
Task-3sTask3 Thread-3
Task-3sTask2 InterruptedException
Task-3sTask2 Thread-2
Task-1sTask1 InterruptedException
Task-1sTask1 Thread-0
Task-3sTask1 InterruptedException
Task-3sTask1 Thread-1
通过结果可以看出当最快的结果返回后,执行器中断了其它所有线程,没有执行的task也从队列里清除了。
3.6 运行多个任务处理所有结果
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)throws InterruptedException;
返回的List<Future<T>>是用来获得任务的结果,因为invokeAll是阻塞的,返回时候所有的任务都已经完成了。
也就是所有的Future对象isDone()都会返回true;通过下面的例子也可以说明这点
public static void main(String[] args) { System.out.println("=========main start"); final ExecutorService exec = Executors.newFixedThreadPool(4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); List<Task> tasks = new ArrayList<Task>(); tasks.add(new Task("2sTask", 2)); tasks.add(new Task("3sTask1", 3)); tasks.add(new Task("3sTask2", 3)); tasks.add(new Task("3sTask3", 3)); tasks.add(new Task("1sTask1", 1)); tasks.add(new Task("1sTask2", 1)); tasks.add(new Task("1sTask3", 1)); tasks.add(new Task("10sTask", 10)); List<Future<String>> results = null; try { results = exec.invokeAll(tasks); } catch (InterruptedException e) { e.printStackTrace(); } for (Future<String> result : results) { try { System.out.println("result = " + result.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } System.out.println("=========main end"); }
=========main start
Task-2sTask Thread-0
Task-1sTask1 Thread-0
Task-3sTask2 Thread-2
Task-3sTask3 Thread-3
Task-3sTask1 Thread-1
Task-1sTask2 Thread-0
Task-1sTask3 Thread-2
Task-10sTask Thread-3
result = Task-2sTask
result = Task-3sTask1
result = Task-3sTask2
result = Task-3sTask3
result = Task-1sTask1
result = Task-1sTask2
result = Task-1sTask3
result = Task-10sTask
=========main end
3.7 [b]ExecutorService和ScheduledExecutorService[/b]
public interface ScheduledFuture<V> extends Delayed, Future<V> { }
ExecutorService中的时间都是timeout,是任务的时限,一般如果在时限内没有完成则中断任务并且清空队列中的任务
boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
ScheduledExecutorService的schedule中的参数是delay,delay是延迟执行
public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit);
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
这里要注意scheduleWithFixedDelay和scheduleAtFixedRate没有callable的参数,只能运行Runnable对象,schedule可以传入Runnable和Callable
3.8 延时执行任务
public static class Task implements Callable<String> { private String id; Task(String id) { this.id = "Task-" + id; } @Override public String call() throws Exception { System.out.println(id + " " + Thread.currentThread().getName()); return id; } } public static void main(String[] args) { System.out.println("=========main start"); final ScheduledExecutorService exec = Executors.newScheduledThreadPool( 1, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); exec.schedule(new Task("[schedule task]"), 5, TimeUnit.SECONDS); try { exec.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("=========main end"); }
=========main start
Task-[schedule task] Thread-0
=========main end
public static void main(String[] args) { System.out.println("=========main start"); final ScheduledExecutorService exec = Executors.newScheduledThreadPool( 1, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); exec.schedule(new Task("[schedule task]"), 5, TimeUnit.SECONDS); try { exec.awaitTermination(1, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("=========main end"); }
=========main start
=========main end
Task-[schedule task] Thread-0
再改改增加一个task并且延迟时间比第一个task短。
public static void main(String[] args) { System.out.println("=========main start"); final ScheduledExecutorService exec = Executors.newScheduledThreadPool( 4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); exec.schedule(new Task("[schedule task1]"), 3, TimeUnit.SECONDS); exec.schedule(new Task("[schedule task2]"), 1, TimeUnit.SECONDS); try { exec.awaitTermination(5, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("=========main end"); }
=========main start
Task-[schedule task2] Thread-0
Task-[schedule task1] Thread-1
=========main end
看看shutdown和shutdownNow能否阻止schedule的task
通过实验shutdown不能阻止schedule的task,仍然按延迟时间执行了,awaitTermination设置失效,不再等待
仍然输出
=========main start
Task-[schedule task2] Thread-0
Task-[schedule task1] Thread-1
=========main end
而exec.shutdownNow();调用后不仅schedule的task都没有执行,awaitTermination也没有作用了 直接输出end了
public static void main(String[] args) { System.out.println("=========main start"); final ScheduledExecutorService exec = Executors.newScheduledThreadPool(4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); exec.schedule(new Task("[schedule task1]"), 3, TimeUnit.SECONDS); exec.schedule(new Task("[schedule task2]"), 1, TimeUnit.SECONDS); // exec.shutdown(); // 这里shutdown不能阻止schedule的task,仍然按延迟时间执行了,awaitTermination设置失效,不再等待10s exec.shutdownNow(); // 这里shutdownNow阻止延迟的task执行,同时awaitTermination设置失效,不再等待 try { exec.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("=========main end"); }
=========main start
=========main end
3.9 setExecuteExistingDelayedTasksAfterShutdownPolicy
下面看看这个方法 ((ScheduledThreadPoolExecutor)exec).setExecuteExistingDelayedTasksAfterShutdownPolicy(false);改变了策略shutdown,传入false时再调用shutdown会产生和shutdownNow一样的效果(不仅schedule的task都没有执行,awaitTermination也没有作用了 直接输出end了)
public static void main(String[] args) { System.out.println("=========main start"); final ScheduledExecutorService exec = Executors.newScheduledThreadPool(4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); exec.schedule(new Task("[schedule task1]"), 3, TimeUnit.SECONDS); exec.schedule(new Task("[schedule task2]"), 1, TimeUnit.SECONDS); /** * 改变了策略shutdown,传入false时再调用shutdown会产生和shutdownNow一样的效果(不仅schedule的task都没有执行,awaitTermination也没有作用了 直接输出end了) */ ((ScheduledThreadPoolExecutor)exec).setExecuteExistingDelayedTasksAfterShutdownPolicy(false); exec.shutdown(); // 由于上面一句改变了shutdow的策略,这里shutdown和shutdownNow效果一样,awaitTermination设置失效,不再等待10s try { exec.awaitTermination(10, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("=========main end"); }
=========main start
=========main end
3.10 周期执行任务
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit);
public d6f0 ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
3.10.1 scheduleAtFixedRate
这个方法比较有意思,没有以Callback作为参数,所以其返回值飞泛型是“?”scheduleAtFixedRate第一个参数是task 不是Callback所以不能返回值,ScheduledFuture应该是用来看执行状态的
initialDelay这个参数是第一task的延时 单位是第四个参数的
period是之后发出任务的间隔
ScheduledFuture继承自Future<V>
public interface ScheduledFuture<V> extends Delayed, Future<V> { }
现在写个demo来试试这个方法
public class Task implements Runnable { private String id; private long creatTime; Task(String id) { this.id = "Task-" + id; creatTime = System.currentTimeMillis(); } @Override public void run() { System.out.println("开始执行 时间:" + ((System.currentTimeMillis() - creatTime) / 1000) + " " + id + " " + Thread.currentThread().getName()); try { // Thread.sleep(2000);// 2s 没有超过了设定的delay时间 会按设定的delay时间进行下一个task Thread.sleep(6000); // 6s 超过了设定的delay时间,会等待task结束再进行下一个task } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("执行结束 " + id + " " + Thread.currentThread().getName()); } }
public class Main { /** * @param args */ public static void main(String[] args) { System.out.println("=========main start"); final ScheduledExecutorService exec = Executors.newScheduledThreadPool(4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); // 延迟1s,然后每隔5s执行一次 // 发现即便线程池中可以有4个线程来处理任务但是任务仍然是处理完了才回发出下一个task,如果task时间超过了设定的delay时间,会等待task结束再进行下一个task ScheduledFuture<?> sf = exec.scheduleAtFixedRate(new Task("[schedule task]"), 1, 5, TimeUnit.SECONDS); System.out.println("=========main end"); } }
上面的如所预料的不断输出。
改一改,
发现即便线程池中可以有4个线程来处理任务但是任务仍然是处理完了才回发出下一个task,如果task时间超过了设定的delay时间,会等待task结束再进行下一个task
log上添加时间看得更清楚;如果task的时间超过的了周期,也要等到task执行完毕后立即发送下个task
看看两种时间情况
public static class Task implements Runnable { //不能再是Callable private String id; Task(String id) { this.id = "Task-" + id; } @Override public void run() { System.out.println(new Date() +":"+ id + " task start " + Thread.currentThread().getName()); try { <strong>TimeUnit.SECONDS.sleep(1);</strong> } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(new Date() +":"+ id + " task end " + Thread.currentThread().getName()); } } public static void main(String[] args) { System.out.println("=========main start"); final ScheduledExecutorService exec = Executors.newScheduledThreadPool( 4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); ScheduledFuture<?> sf = exec.scheduleAtFixedRate(new Task("[schedule task1]"), 1, 5, TimeUnit.SECONDS); System.out.println("=========main end"); }
=========main start
=========main end
Sat Nov 15 14:38:58 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:38:59 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:39:03 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:39:04 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:39:08 CST 2014:Task-[schedule task1] task start Thread-1
Sat Nov 15 14:39:09 CST 2014:Task-[schedule task1] task end Thread-1
Sat Nov 15 14:39:13 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:39:14 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:39:18 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:39:19 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:39:23 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:39:24 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:39:28 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:39:29 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:39:33 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:39:34 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:39:38 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:39:39 CST 2014:Task-[schedule task1] task end Thread-0
倘若task执行的时间大于delay的时间,会在执行完task立即发出下一个task,而不是在没执行完上个task的时候 又发出一个task,虽然此时有空闲线程
public static class Task implements Runnable { private String id; Task(String id) { this.id = "Task-" + id; } @Override public void run() { System.out.println(new Date() +":"+ id + " task start " + Thread.currentThread().getName()); try { <strong>TimeUnit.SECONDS.sleep(10);</strong> } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(new Date() +":"+ id + " task end " + Thread.currentThread().getName()); } } public static void main(String[] args) { System.out.println("=========main start"); final ScheduledExecutorService exec = Executors.newScheduledThreadPool( 4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); ScheduledFuture<?> sf = exec.scheduleAtFixedRate(new Task("[schedule task1]"), 1, 5, TimeUnit.SECONDS); System.out.println("=========main end"); }=========main start
=========main end
Sat Nov 15 14:40:14 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:40:24 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:40:24 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:40:34 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:40:34 CST 2014:Task-[schedule task1] task start Thread-1
Sat Nov 15 14:40:44 CST 2014:Task-[schedule task1] task end Thread-1
Sat Nov 15 14:40:44 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:40:54 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:40:54 CST 2014:Task-[schedule task1] task start Thread-0
3.10.2 scheduleWithFixedDelay
public static class Task implements Runnable { private String id; Task(String id) { this.id = "Task-" + id; } @Override public void run() { System.out.println(new Date() +":"+ id + " task start " + Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(new Date() +":"+ id + " task end " + Thread.currentThread().getName()); } } public static void main(String[] args) { System.out.println("=========main start"); final ScheduledExecutorService exec = Executors.newScheduledThreadPool( 4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); ScheduledFuture<?> sf = exec.scheduleWithFixedDelay(new Task("[schedule task1]"), 1, 5, TimeUnit.SECONDS); System.out.println("=========main end"); }
=========main start
=========main end
Sat Nov 15 14:42:24 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:42:25 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:42:30 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:42:31 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:42:36 CST 2014:Task-[schedule task1] task start Thread-1
Sat Nov 15 14:42:37 CST 2014:Task-[schedule task1] task end Thread-1
Sat Nov 15 14:42:42 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:42:43 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:42:48 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:42:49 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:42:54 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:42:55 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:43:00 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:43:01 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:43:06 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:43:07 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:43:12 CST 2014:Task-[schedule task1] task start Thread-0
可以看此时 是 任务结束后再延迟固定的时间
public static class Task implements Runnable { private String id; Task(String id) { this.id = "Task-" + id; } @Override public void run() { System.out.println(new Date() + ":" + id + " task start " + Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(new Date() + ":" + id + " task end " + Thread.currentThread().getName()); } } public static void main(String[] args) { System.out.println("=========main start"); final ScheduledExecutorService exec = Executors.newScheduledThreadPool( 4, new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); ScheduledFuture<?> sf = exec.scheduleWithFixedDelay(new Task( "[schedule task1]"), 1, 5, TimeUnit.SECONDS); System.out.println("=========main end"); }=========main start
=========main end
Sat Nov 15 14:43:58 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:44:08 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:44:13 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:44:23 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:44:28 CST 2014:Task-[schedule task1] task start Thread-1
Sat Nov 15 14:44:38 CST 2014:Task-[schedule task1] task end Thread-1
Sat Nov 15 14:44:43 CST 2014:Task-[schedule task1] task start Thread-0
Sat Nov 15 14:44:53 CST 2014:Task-[schedule task1] task end Thread-0
Sat Nov 15 14:44:58 CST 2014:Task-[schedule task1] task start Thread-0
3.11 取消在执行的任务
Future#cancel(true);是可以发出中断信号,但是线程仍然在一直运行。如果任务还没有开始处理,cancel则会让任务不再被处理。
如果任务已经开始则会发出中断信号 任务会继续运行。、
(???如何理解中断信号,一个线程中如果有sleep产生中断信号后使之抛出中断异常,但如果线程中是一个死循环,中断信号并不能使之停止循环???)(???中断异常抛出的原理???)
public static class Task implements Runnable { private String id; Task(String id) { this.id = "Task-" + id; } @Override public void run() { System.out.println(new Date() + ":" + id + " task start " + Thread.currentThread().getName()); while(true) { System.out.println(new Date() + ":" + id + " task running " + Thread.currentThread().getName()); } } } public static void main(String[] args) { System.out.println("=========main start"); final ExecutorService exec = Executors.newSingleThreadExecutor( new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); Future<?> f = exec.submit(new Task("task")); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } f.cancel(true); System.out.println("=========main end"); }
3.12 FutureTask
public static class Task implements Callable<String> { private String id; Task(String id) { this.id = "Task-" + id; } @Override public String call() throws Exception { System.out.println(id + " " + Thread.currentThread().getName()); return id; } } public static void main(String[] args) { System.out.println("=========main start"); final ExecutorService exec = Executors .newSingleThreadExecutor(new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r); } }); FutureTask<String> ftask = new FutureTask<String>(new Task("task")){ @Override protected void done() { System.out.println("=========FutureTask done"); super.done(); } }; exec.submit(ftask); System.out.println("=========main end"); }=========main start
=========main end
Task-task Thread-0
=========FutureTask done
相关文章推荐
- Java并发编程高级篇(二):使用固定大小线程执行器
- 【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
- java并发--Daemon后台线程的使用
- 【java并发】线程并发库的使用
- java并发编程之线程执行器
- java并发线程---线程的使用
- 使用Java线程并发库实现两个线程交替打印的线程题
- 【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
- 【java并发】线程锁技术的使用
- Java并发和多线程4:使用通用同步工具CountDownLatch实现线程等待
- java使用Executor(执行器)管理线程
- 【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
- Java并发学习之九——使用本地线程变量
- java线程并发blockingqueue类使用示例
- Java并发——使用Condition线程间通信
- 【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
- java使用Executor(执行器)管理线程
- java中的并发:线程的基本使用
- 【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明(r)
- java挑战高并发 之(10):使用wait/notify/notifyAll实现线程间通信的几点重要说明