多线程并发处理,线程池!
方式 | 抛出异常 | 有返回值 | 阻塞等待 | 超时等待 |
---|---|---|---|---|
添加 | add | offer | put | offer(,) |
移除 | remove | poll | take | poll(,) |
检测队列首 | element | peek |
/**
* 抛出异常
*/
public static void test01(){
//队列的大小,即最多放多少个数据
ArrayBlockingQueue queue = new ArrayBlockingQueue(3);
System.out.println(queue.add("a"));
System.out.println(queue.add("b"));
System.out.println(queue.add("c"));
//java.lang.IllegalStateException: Queue full 抛出异常!
System.out.println(queue.add("d"));
System.out.println("===============");
System.out.println(queue.remove());
System.out.println(queue.remove());
System.out.println(queue.remove());
//java.util.NoSuchElementException 抛出异常!
System.out.println(queue.remove());
}
/**
* 有返回值,没有异常
*/
public static void test02(){
//队列的大小,即最多放多少个数据
ArrayBlockingQueue queue = new ArrayBlockingQueue(3);
System.out.println(queue.offer("a"));
System.out.println(queue.offer("b"));
System.out.println(queue.offer("c"));
//false 不抛出异常!
System.out.println(queue.offer("d"));
System.out.println("===============");
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
//null 不抛出异常!
System.out.println(queue.poll());
}
/**
* 等待,阻塞(一直阻塞)
*/
public static void test03() throws InterruptedException {
//队列的大小,即最多放多少个数据
ArrayBlockingQueue queue = new ArrayBlockingQueue(3);
//无返回值,一直阻塞
queue.put("a");
queue.put("b");
queue.put("c");
//队列没有位置了,线程会一直等待
queue.put("d");
System.out.println(queue.take());
System.out.println(queue.take());
System.out.println(queue.take());
//没有这个元素,线程会一直等待
System.out.println(queue.take());
}
/**
* 等待,阻塞(超时等待)
*/
public static void test04() throws InterruptedException {
//队列的大小,即最多放多少个数据
ArrayBlockingQueue queue = new ArrayBlockingQueue(3);
queue.offer("a",10L, TimeUnit.SECONDS);
queue.offer("b",10L, TimeUnit.SECONDS);
queue.offer("c",10L, TimeUnit.SECONDS);
//等待超过5秒就退出
queue.offer("d",5L, TimeUnit.SECONDS);
System.out.println(queue.poll());
System.out.println(queue.poll());
System.out.println(queue.poll());
//等待超过2秒就退出
System.out.println(queue.poll(2L,TimeUnit.SECONDS));
}
/**
* 同步队列
* 和其他的BlockingQueue 不一样, synchronousQueue 不存储元素
* 即 put了一个元素,必须从里面先take取出来,否则不能再put进去
*/
BlockingQueue<String> synchronousQueue = new SynchronousQueue<>();
new Thread(()->{
try {
synchronousQueue.put("1");
synchronousQueue.put("2");
synchronousQueue.put("3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(3L);
System.out.println(synchronousQueue.take());
TimeUnit.SECONDS.sleep(3L);
System.out.println(synchronousQueue.take());
TimeUnit.SECONDS.sleep(3L);
System.out.println(synchronousQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
事先准备好一些资源,有人要用,就来这里拿,用完还
线程池、连接池、内存池、对象池…创建、销毁。十分浪费资源
- 降低资源的消耗
- 提高响应的速度
- 方便管理
线程复用,可以控制最大并发数、管理线程
// 本质都是threadPoolExecutor
ExecutorService threadPool =
// Executors.newSingleThreadExecutor();// 单个线程
// Executors.newFixedThreadPool(5); // 创建固定的线程池的大小
Executors.newCachedThreadPool(); // 可伸缩的
public ThreadPoolExecutor(int corePoolSize, //核心线程数量
int maximumPoolSize, //非核心线程数量
long keepAliveTime, // 非核心线程保持时长,超时了没有人调用就会释放
TimeUnit unit, // 时长单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂(创建线程的,一般不用动)
RejectedExecutionHandler handler) // 拒绝策略
new ThreadPoolExecutor.AbortPolicy()
new ThreadPoolExecutor.CallerRunsPolicy()
new ThreadPoolExecutor.DiscardPolicy()
new ThreadPoolExecutor.DiscardOldestPolicy()
- CPU 密集型:几核就是几,可以保持CPU的效率最高
int num = Runtime.getRuntime().availableProcessors();- IO 密集型:判断程序中十分耗IO的程序数量,可为两倍
// 没有返回值,直接提交任务( Runnable )
ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>());
pool.execute(new Runnable() {
@Override
public void run() {
}
});
// 有返回值,传入的是FutureTask接口实现类
Future<?> submit = pool.submit(new FutureTask<Integer>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 1;
}
}));
// 通过get获取返回值,若线程还没执行完会先阻塞
try {
Object o = submit.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}