使用Java.util.concurrent包下的类
一些概念:
- 阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回
采用LockSupport.park()
阻塞住线程, 采用LockSupport.unpark(Thread)
释放进程。 - 队列:生产者消费者模式首选数据模式为队列。Java提供的线程安全的队列可分为阻塞队列(BlockingQueue)和非阻塞队列(ConcurrentLinkedQueue).根据需要选择阻塞队列还是非阻塞队列。
- 线程安全:指类内共享的全局变量的访问必须保证是不受多线程形式影响的。如果由于多线程的访问(比如修改、遍历、查看)而使这些变量结构被破坏或者针对这些变量操作的原子性被破坏,则这个类就不是线程安全的。
阻塞队列: BlockingQueue
实现类:
详细介绍:http://www.cnblogs.com/geningchao/p/6638781.html
ArrayBlockingQueue: 规定大小
LinkedBlockingQueue: 大小可规定,不规定为Interger.MAX_VALUE来决定。
PriorityBlockingQueue: 更加优先级来决定出队列顺序
SynchronousQueue: 无缓存的等待队列。
DelayQueue: 延迟队列
方法:
操作 | 失败 | 抛出异常 | 特殊值false | 阻塞 超时 |
---|---|---|---|---|
插入 | Add(e) | Offer(e) | Put(e) | Offer(e,time, TimeUnit) |
移除 | Remove() | Poll() | Take() | Poll(time, TimeUnit) |
检查 | element | Peek() |
双端阻塞队列:BlockingDeque
该接口是一种双端队列,向其中加入元素或取出元素都是现成安全的,如果不能对双端队列进行加入或删除元素,则会阻塞线程。
非阻塞队列: ConcurrentHashMap
多线程:
声明线程的方法:
- 继承Thread extends Thread();
- 实现接口Runnable implements Runnable(); 无返回值。 一般运行:new Thread(new
Runable()).start(); - implements Callable (有返回值); 执行 ,Callable.call()
异步执行框架Executor框架:
支持多种不同类型的任务执行策略,提供了一种标准的方法将任务的提交过程和执行过程解耦开发,基于生产者-消费者模式,其提交任务的线程相当于生产者,执行任务的线程相当于消费者,并用Runnable来表示任务,Executor的实现还提供了对生命周期的支持,以及统计信息收集,应用程序管理机制和性能监视等机制。
Executor 子接口 ExecutorService
实现类:
AbstractExecutorService: 默认实现类
ScheduledExecutorService: 一个可定时调度任务的接口
ScheduledThreadPoolExecutor: ScheduledExecutorService实现类
ThreadPoolExecutor: 线程池,通过调用Executors中的静态方法来创建线程池并返回一个ExecutorService对象。
Executor的生命周期:
- 运行 创建即运行;
- 关闭 shutdown 执行完已提交的任务关闭
- 终止 shutdownNow 强制终止所有运行中的任务,并不允许添加新的任务。
Executor 执行任务:
Executor.submit(new Runnable()); 或 Executor.execute(new Runnable())
Future f = Executor.submit(new Callable); 有返回值 f.get()
Executors
提供一系列静态工厂方法用于创建各种线程池
//创建方法
//创建可重用且固定线程数的线程池。数量够了再来则等待。
ExecutorService executor = Executors.newFixedThreadPool(int num)
//创建一个单线程的Executor. 如果异常结束则新建线程来执行后续任务
Executors.newSingleThreadExecutor()
//创建一个可延迟执行或定期执行的线程池
Executors.newScheduledThreadPool(int corePoolSize)
//创建可缓存的线程池。六十秒没用则清除。
Executors.newCachedThreadPool()
示例:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import com.thunisoft.artery.report.crs.engine.callback.imp.Callback;
import com.thunisoft.artery.services.config.ArteryConfigUtil;
@Service
public class RequestThreadHandle {
private static int queue_size;
private static int EXE_SIZE;
private static BlockingQueue<ThreadBean> queue;
private static ThreadPoolExecutor executorService;
//初始化
@PostConstruct
public void init() {
int queue_size = 200;
queue = new LinkedBlockingQueue<ThreadBean>(queue_size);
orc_size = 10;
executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(orc_size);
}
/**
* 添加到队列中
* @param httpBean
* @return
* @throws InterruptedException
*/
public boolean offerQuery(ThreadBean httpBean) throws InterruptedException {
return queue.offer(httpBean);
}
@PostConstruct
public void consume() throws InterruptedException, ExecutionException{
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
ThreadBean httpBean = queue.poll();
if (httpBean == null) {
continue;
}
executorService.submit(httpBean);
}
}
}
});
t.start();
}
//销毁
@PreDestroy
public void CloseExe() {
executorService.shutdown();
}
}
public class ThreadBean extends Thread{
@Override
public void run() {
//do your thing
}
}