2018-09-28 18:46:04 faker____ 阅读数 832更多
分类专栏: java
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/faker____/article/details/82888392
-
package ThreadPools_5;
-
import java.util.ArrayList;
-
import java.util.List;
-
import java.util.Random;
-
import java.util.concurrent.ExecutorService;
-
import java.util.concurrent.Executors;
-
import java.util.concurrent.TimeUnit;
-
/**
-
* This is the implementation of {@link LockObjects_4.Worker} with threadPool
-
* <br><br>
-
* Codes with minor comments are from
-
* <a href="http://www.caveofprogramming.com/youtube/">
-
* <em>http://www.caveofprogramming.com/youtube/</em>
-
* </a>
-
* <br>
-
* also freely available at
-
* <a href="https://www.udemy.com/java-multithreading/?couponCode=FREE">
-
* <em>https://www.udemy.com/java-multithreading/?couponCode=FREE</em>
-
* </a>
-
*
-
* @author Z.B. Celik <celik.berkay@gmail.com>
-
*/
-
class Worker implements Runnable {
-
private Random random = new Random();
-
private final Object lock1 = new Object();
-
private final Object lock2 = new Object();
-
public List<Integer> list1 = new ArrayList<Integer>();
-
public List<Integer> list2 = new ArrayList<Integer>();
-
public void run() {
-
process();
-
}
-
public void process() {
-
for (int i = 0; i < 1000; i++) {
-
stageOne();
-
stageTwo();
-
}
-
}
-
public void stageOne() {
-
synchronized (lock1) {
-
try {
-
Thread.sleep(1);
-
} catch (InterruptedException e) {
-
//do your work here
-
e.printStackTrace();
-
}
-
list1.add(random.nextInt(100));
-
}
-
}
-
public void stageTwo() {
-
synchronized (lock2) {
-
try {
-
Thread.sleep(1);
-
} catch (InterruptedException e) {
-
//do your work here
-
e.printStackTrace();
-
}
-
list2.add(random.nextInt(100));
-
}
-
}
-
}
-
public class WorkerThreadPool {
-
public static void main(String[] args) {
-
ExecutorService executor = Executors.newFixedThreadPool(2);//two threads, try setting by 1 to observe time
-
System.out.println("Starting ...");
-
long start = System.currentTimeMillis();
-
Worker worker = new Worker();
-
for (int i = 0; i < 2; i++) {//worker.run is called 2 (threads started) times by two threads
-
executor.submit(worker);
-
}
-
executor.shutdown(); //prevents new tasks from being accepted by the ExecutorService
-
try {
-
executor.awaitTermination(1, TimeUnit.DAYS);
-
// How long should I wait for termination If I do not know exactly when threads are done with the tasks ?
-
// Source:http://stackoverflow.com/questions/1250643/how-to-wait-for-all-threads-to-finish-using-executorservice
-
// For a perpetually running batch kind of thing u need to submit jobs and wait for them to
-
// finish before jumping ahead.
-
// In Such a case a latch or a barrier makes more sense than a shutdown (see CountDownLatch_6.App).
-
} catch (Exception ex) {
-
System.out.println(ex.getMessage());
-
}
-
long end = System.currentTimeMillis();
-
System.out.println("Time taken: " + (end - start));
-
System.out.println("List1: " + worker.list1.size() + "; List2: " + worker.list2.size());
-
}
-
}
上述代码执行后控制台打印
Starting ...
Time taken: 2183
List1: 2000; List2: 2000
-
shutdown方法:平滑的关闭ExecutorService,当此方法被调用时,ExecutorService停止接收新的任务并且等待已经提交的任务(包含提交正在执行和提交未执行)执行完成。当所有提交任务执行完毕,线程池即被关闭。
-
awaitTermination方法:接收人timeout和TimeUnit两个参数,用于设定超时时间及单位。当等待超过设定时间时,会监测ExecutorService是否已经关闭,若关闭则返回true,否则返回false。一般情况下会和shutdown方法组合使用。
3.shutdownNow方法的作用是向所有执行中的线程发出interrupted以中止线程的运行。这时,各个线程会抛出 InterruptedException异常(前提是
线程中运行了sleep等会抛出异常的方法)
在上述代码中 shutdown方法的意思是等待当前正在执行的线程执行完毕 并且停止接受新的线程执行,如果新开线程的话会抛出RejectedExecutionException异常
awaitTermination的第一个参数是时间,第二个参数是时间单位,在这个地方监视线程是否都执行完毕,如果执行完毕后会执行后面的代码
一般情况下awaitTermination和shutdown配合使用,在上述代码中如果注释掉shutdown方法则awaitTermination不会监视到线程池关闭的信息 所以在这个地方代码会堵塞,
如果注释掉awaitTermination方法 则后面的代码不会得到线程执行过的结果
控制台结果
Starting ...
Time taken: 2
List1: 0; List2: 0
参考资料 点这里