记录下线程的几种形式以及写法:
缓存线程池 Executors.newCacheThreadPool();
ExecutorService chacheThreadPool = Executors.newCachedThreadPool();
try {
for (int i = 0; i < 10; i++) {
//加上休眠后,会发现因为用完销毁后,一直用的同一个线程,没有创建新线程
Thread.sleep(100);
chacheThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在被执行中...");
}
});
}
} catch (Exception e) {
// TODO: handle exception
}
输出结果:(因为睡眠,前面的线程已经被销毁,重新使用原来的线程)
pool-1-thread-1正在被执行中...
pool-1-thread-1正在被执行中...
pool-1-thread-1正在被执行中...
pool-1-thread-1正在被执行中...
pool-1-thread-1正在被执行中...
pool-1-thread-1正在被执行中...
pool-1-thread-1正在被执行中...
pool-1-thread-1正在被执行中...
pool-1-thread-1正在被执行中...
pool-1-thread-1正在被执行中...
去掉sleep后:生成多个线程
pool-1-thread-1正在被执行中...
pool-1-thread-6正在被执行中...
pool-1-thread-7正在被执行中...
pool-1-thread-4正在被执行中...
pool-1-thread-5正在被执行中...
pool-1-thread-3正在被执行中...
pool-1-thread-2正在被执行中...
pool-1-thread-8正在被执行中...
pool-1-thread-10正在被执行中...
pool-1-thread-9正在被执行中...
固定数量的线程池 Executors.newFixedThreadPool(int n);
代码变更:
ExecutorService chacheThreadPool = Executors.newFixedThreadPool(3);
指定数量的线程池。
输出:
pool-1-thread-1正在被执行中...
pool-1-thread-2正在被执行中...
pool-1-thread-3正在被执行中...
pool-1-thread-1正在被执行中...
pool-1-thread-2正在被执行中...
pool-1-thread-3正在被执行中...
pool-1-thread-1正在被执行中...
pool-1-thread-2正在被执行中...
pool-1-thread-3正在被执行中...
pool-1-thread-1正在被执行中...
调度线程池,支持定时及周期性任务执行 Executors.newScheduledThreadPool(int n):
ScheduledExecutorService chacheThreadPool = Executors.newScheduledThreadPool(3);
try {
for (int i = 0; i < 10; i++) {
//指定最大3个线程数。延迟3秒后执行
chacheThreadPool.schedule(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在被执行中...");
}
},3,TimeUnit.SECONDS);
}
} catch (Exception e) {
// TODO: handle exception
}
ScheduledExecutorService chacheThreadPool = Executors.newScheduledThreadPool(4);
try {
for (int i = 0; i < 10; i++) {
//延迟1秒后每3秒执行一次
chacheThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在被执行中...");
}
},1,3,TimeUnit.SECONDS);
}
} catch (Exception e) {
// TODO: handle exception
}
单线程线程池 Executors.newSingleThreadExecutor()
ExecutorService chacheThreadPool = Executors.newSingleThreadExecutor();
try {
for (int i = 0; i < 10; i++) {
//加上休眠后,会发现因为用完销毁后,一直用的同一个线程,没有创建新线程
Thread.sleep(100);
chacheThreadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"正在被执行中...");
}
});
}
} catch (Exception e) {
// TODO: handle exception
}
单线程线程池只能同时执行一个线程。
自定义线程池 ThreadPoolExecutor和BlockingQueue连用
1. 缓冲队列BlockingQueue简介:
BlockingQueue是双缓冲队列。BlockingQueue内部使用两条队列,允许两个线程同时向队列一个存储,一个取出操作。在保证并发安全的同时,提高了队列的存取效率。
2. 常用的几种BlockingQueue:
- ArrayBlockingQueue(int i):规定大小的BlockingQueue,其构造必须指定大小。其所含的对象是FIFO顺序排序的。
- LinkedBlockingQueue()或者(int i):大小不固定的BlockingQueue,若其构造时指定大小,生成的BlockingQueue有大小限制,不指定大小,其大小有Integer.MAX_VALUE来决定。其所含的对象是FIFO顺序排序的。
- PriorityBlockingQueue()或者(int i):类似于LinkedBlockingQueue,但是其所含对象的排序不是FIFO,而是依据对象的自然顺序或者构造函数的Comparator决定。
- SynchronizedQueue():特殊的BlockingQueue,对其的操作必须是放和取交替完成。
3. 自定义线程池(ThreadPoolExecutor和BlockingQueue连用):
自定义线程池,可以用ThreadPoolExecutor类创建,它有多个构造方法来创建线程池。
常见的构造函数:ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
public class ThreadCachePoolTest {
public static void main(String[] args) {
// 创建数组型缓冲等待队列
BlockingQueue<Runnable> bq = new ArrayBlockingQueue<Runnable>(10);
// ThreadPoolExecutor:创建自定义线程池,池中保存的线程数为3,允许最大的线程数为6
ThreadPoolExecutor tpe = new ThreadPoolExecutor(3, 6, 50, TimeUnit.MILLISECONDS, bq);
ThreadTest t1 = new ThreadTest();
ThreadTest t2 = new ThreadTest();
tpe.execute(t1);
tpe.execute(t2);
}
}
class ThreadTest implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"执行中..");
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
}
}
输出:
pool-1-thread-1执行中..
pool-1-thread-2执行中..
参考资料:
https://blog.youkuaiyun.com/hnd978142833/article/details/80253784