ExecutorService线程池中多线程操作同一变量
2017-07-12 本文已影响114人
18587a1108f1
ExecutorService
java中在java.util.concurrent包下,提供ExecutorService对象,可用于创建线程池,用于多线程情境。
//创建10个线程的线程池
ExecutorService service = Executors.newFixedThreadPool(10);
service.submit(task1());
service.submit(task2());
.....
service.shutdown();
这里sumbit()方法加入任务task1后,线程池中的任务不会立即执行,而是会先向后执行,一直到线程池满了或者任务全加入后执行到shutdown()。
shutdown()的意思为不再加入任务,等待当前线程池中的任务执行完成。所以这个时候会再去执行各个线程中的任务,这样的好处是可以避免服务因为某个任务而停止执行,而是把任务先加入执行队列,保证整体的正常顺利执行,再去执行每个任务细节。
多线程计数
当需要统计各个线程中某项共通任务的执行次数时,一般需要加锁解锁操作来保证原子性,java中提供了现有的类型来帮助多线程计数,非常方便。
** AtomicInteger** 提供set()和addAndSet()等方法,可实现多线程的原子操作
//在类下声明一个AtomicInteger变量,用于计数
private static AtomicInteger num = new AtomicInteger();
.....
//写一个初始化方法,用AtomicInteger自带的set方法初始化
private static void safeInitial(){
num.set(0);
}
...
//多线程的任务task1()中要计数的地方
...
//addAndGet是指add一个值(这里是1),并且得到加后的结果,我们不需结果,就执行即可
num.addAndGet(1);
...
//最后在service.shutdown后输出计数结果(要在线程都执行完输出统计结果)
...
service.shutdown();
while (true) { //一直循环执行
if (service.isTerminated()) {//判断service中的线程是否都执行完
System.out,println(num);
break;
}
Thread.sleep(1000); //每隔1s执行一次循环判断,减少资源消耗
}
....
这样我们就完成了多线程中的计数问题,在多线程中合法的操作同一变量完成了计数。