1.实现线程的方式
- Thread
- Runnable
- Callable
- 效率较高
2.线程的六个状态
- NEW
- RUNNABLE
- BLOCKED
- WATTING
- 无限期等待
- TIMED_WATTING
- 超时等待,当时间到了,会释放锁
- TERMINATED
3.wait&&sleep
- 来自不同的类,wait来自object,sleep来自thread
- wait会释放锁,sleep不会释放
- wait必须在同步代码块中使用,sleep可以在任何地方使用
- wait不需要捕获异常,sleep必须要捕获异常
4.synchronized&&lock
- synchronized是关键字,lock是java类
- synchronized会自动释放,lock必须要手动释放,如果不释放就会发生死锁
- synchronized适合少量的锁代码问题,lock适合锁大量的同步代码
5.lock的使用方法
加锁–>业务代码–>解锁,业务代码和解锁需要在try catch中进行
6.synchronized锁的对象问题
- 当synchronized加在普通方法上时,锁的是方法的调用者
- 加在static方法时,类一加载就出现了,锁的是class
7.callable的使用方法
中间需要FutureTask类适配
Callable和Runnable的区别:
- 方法不同。一个是run(),一个是call()
- run()没有异常,call()需要抛出异常
- run()返回值void,call()有返回值
8.ArrayList线程不安全解决办法
-
故障现象,抛出异常
- 俗称并发修改异常
-
ArrayList线程不安全,解决方法
-
使用vector线程安全,其add()方法加了synchronized关键字
-
此工具类方法可以使hashset、hashmap加锁 -
List<String> list=new CopyOnWriteArrayList<>();
使用CopyOnWriteArrayList<>()类
-
CopyOnWrite容器即写时复制的容器。待一个容器添加元素的时候,不直接往当前容器Object[]添加,而是先将当前容器Object[]进行copy,复制出一个新的容器Object[] newELements,然后新的容器Object[ ] newELements里添加元素,添加完元素之后,再将原容器的引用指向新的容器setArray (newELements)。
这样做的好处是可以对CopyOnWrite容器进行并发的读,而不需要加锁(区别于VectorCollections.synchronizedList()),因为当前容器不会添加任何元素。所以CopyOnWrite容器也是一种读写分离的思想,读和写不同的容器。
9.线程池
线程池做的工作只是控制运行的线程数量,处理过程中将任务放入队列
优势:
- 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的损耗
- 提高响应速度。当任务到达时,任务可以不需要等待线程创建就能执行
- 提高线程的可管理性。线程是稀缺资源,无限制的创建会消耗系统资源,使用线程池可以分配监控和调优
10.线程池架构
线程池重要类ThreadPoolExecutor
11.线程池的种类极其使用场景
这三种线程方法源码上都是一种方法,即通过 ThreadPoolExecutor类得到
12.如何使用线程池
public static void main(String[] args){
//ExecutorService threadPool= Executors.newFixedThreadPool(5);//一池受用五个线程
//ExecutorService threadPool=Executors.newSingleThreadExecutor();//一池一个线程
ExecutorService threadPool=Executors.newCachedThreadPool();//可扩展,一池N线程
try{
for (int i = 0; i <10 ; i++) {
threadPool.execute(()->{
System.out.println(Thread.currentThread().getName()+"办理业务");
});
}
}
catch (Exception e){
e.printStackTrace();
}finally {
threadPool.shutdown();//关闭线程池
}
}
13.线程池的重要七个参数
corePoolSize可以设置常驻核心线程数,maxmumPoolSize可以设置最大线程数,还可以设置空闲线程的存活时间,时间到了就会清理空闲线程,剩下常驻线程。如果线程池满了,后面的任务会进入候客区等待,即进入阻塞队列等待
14.工作中线程池的使用经验
自定义线程池的方式
15.线程池的拒绝策略
定义:
- 当线程池的等待队列排满了,线程的max线程数也达到了,无法为新请求提供服务,这时候就需要拒绝策略来处理问题
jdk的内置拒绝策略: