-
ThreadLocal
可以看做是一个Map ,key 相当于Thread.getCurrentTread
value 存放线程需要保存的变量。ThreadLocal.set(value) ==> map.put(Thread.getCurrentTread,value);
TreadLocal.get(); ==> map.get(Thread.getCurrentThread());
在使用TreadLocal 时,需要注意资源回收,每个线程结束前,将当前线程保存的线程变量一定要删除。TreadLocal.remove();
2, 常见的并发容器
1> ConcurrentHashMap
2>ConcurrentSkipListMap
3>CopyOnWriteList
4>ConcurrentLinkedQueue 队列,链表实现
常用方法:queue.offer(“test”) //添加元素
queue.size() //查看队列长度
queue.peek() //查看对列中的首元素
queue.poll() //获取队列中的首元素,队列长度会减少
5>BlockingQueue 的实现:
LinkedBlockingQueue:
有put和take 方法,队列满或者为空时会自动阻塞。
ArrayBlockingQueue:
add 方法:在容量不足的情况下直接抛出异常
put 方法:在容量不足的时候会阻塞,是可以打断的
offer方法:单参数无阻塞,容量不足时返回false,放弃当前新增的数据, 三参数方法 offer(value,times,timeunit), 容量不足时,阻塞times时长(单位是timeunit), 如果在阻塞时长内,有容量空闲,新增数据返回true。如果阻塞时长范围内,无容量空闲,放弃新增数据,返回false
TransferQueue:
并发容器 - LinkedTransferQueue 转移队列
add - 队列会保存数据,不做阻塞等待。
transfer - 是TransferQueue的特有方法。必须有消费者(take()方法的调用者)。 如果没有任意线程消费数据,transfer方法阻塞。一般用于处理即时消息。
线程池
Executor : 线程池底层处理机制
public class Test_01_MyExecutor implements Executor {
@Overridepublic void execute(Runnable command) {
new Thread(command).start();
}
public static void main(String[] args) {
new Test_01_MyExecutor().execute(
new Runnable(){
public void run(){
System.out.println("线程方法被执行")
}
}
);
}
ExecutorService
Executor的子接口,提供了新的服务方法submit。
该方法可以有Future类型的返回值。需要传入Callable参数
常见方法 - void execute(Runnable), Future submit(Callable), Future submit(Runnable)
Callable
可执行接口,类似于Runnable接口,也是可以启动线程的接口。其中定义的方法是call,call方法的作用和Runnable接口中的run方法是一致的。call方法有返回值
-
FixedThreadPool: 固定容量线程池。创建线程池的时候,容量固定。
-
ScheduledThreadPool: 计划任务线程池, 可以根据计划自动执行任务。
runnable - 要执行的任务。
start_limit - 第一次任务执行的间隔。
limit - 多次任务执行的间隔。
timeunit - 多次任务执行间隔的时间单位
ScheduledExecutorServiceservice=Executors.newScheduledThreadPool(3);
service.scheduleAtFixedRate(Runnable, start_limit,
limit, timeunit)//
-
SingleThreadExecutor
单一容量的线程池。
使用场景: 保证任务顺序时使用。 -
ThreadPoolExecutor
//模拟fixedThreadPool, 核心线程5个,最大容量5个,线程的生命周期无限ExecutorService service = new ThreadPoolExecutor(5, 5, 0L,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue());