在 Java 5.0 提供了 java.util.concurrent (简称JUC )包,在此包中增加了在并发编程中很常用的实用工具类,用于定义类似于线程的自定义子系统,包括线程池、异步 IO 和轻量级任务框架。提供可调的、灵活的线程池。还提供了设计用于多线程上下文中的 Collection 实现等。
下面介绍一下JUCExecutorService的用法:
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
}
}).start();
(1)线程的创建和释放,需要占用不小的内存和资源,每次new Thread新建对象性能差。
(2)线程缺乏统一管理,相互之间存在资源竞争,可能会占用过多资源而导致死机或者OOM
(3)功能单一,缺乏定时执行,定期执行,线程中断等。
(1)重用存在的线程,减少对象创建、消亡的开销,性能较好。
(2)可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
(3)提供定时执行,定期执行,单线程,并发数控制等功能。
ExecutorService是Java提供的线程池,也就是,每次需要使用线程时,可以通过Executor获取线程。它可以有效控制最大并发线程数,提高系统资源使用率,同时避免过多资源竞争阻塞,同时提供定时执行、定期执行、单线程、并发数控制等功能,也不用使用TimeTask了。
Java通过Executors提供四种线程池:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor创建一个单线程化线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。
package com.disruptor.demo.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 可缓存线程池
* @author 零落尘土
*
*/
public class ExectorServiceTest {
public static void main(String[] args) {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
int index = i;
try {
Thread.sleep(index * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" "+index);
}
});
}
cachedThreadPool .shutdown();
}
}
运行结果如下:
设置线程池为5
package com.disruptor.demo.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 固定线程池
* @author 零落尘土
*
*/
public class ExectorServiceFixPoolTest {
public static void main(String[] args) {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
final Integer index = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+"->"+index.hashCode());
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
fixedThreadPool.shutdown();
}
}
运行结果:
package com.disruptor.demo.test;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 定长线程池,支持定时及周期性任务
* @author 零落尘土
* @since 2019-10-30
*/
public class ExectorServiceScheduledTest {
public static void main(String[] args) {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() {
public void run() {
System.out.println(Thread.currentThread().getName()+":delay 3 seconds");
}
},3, TimeUnit.SECONDS);
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+":delay 1 seconds, and excute every 3 seconds");
}
}, 1, 3, TimeUnit.SECONDS);
}
}
执行结果:
package com.disruptor.demo.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 单线程池
* @author 零落尘土
* @since 2019-10-30
*/
public class ExectorServiceSingleTest {
public static void main(String[] args) {
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName()+":"+index);
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
}
执行结果:
现在大多数GUI程序都是单线程。适用于批量删除,批量安装等不适合并发但是可能IO阻塞的操作。