线程安全问题
当多个线程同时操作同一个共享资源的时候,可能会出现结果不符合预期的问题
解决安全问题
方式一: 同步代码块
作用:
把访问共享资源的核心代码给上锁,以此保证线程安全
格式:
synchronized(同步锁) {
访问共享资源的核心代码
}
原理:
每次只允许一个线程加锁后进入,执行完毕后自动解锁,其他线程才可以进来执行。
同步锁的注意事项
1.对于当前同时执行的线程来说,同步锁必须是同一把(同一个对象),否则会出bug
2.对于实例方法建议使用this作为锁对象 对于静态方法建议使用字节码(类名.class)对象作为锁对象
同步代码块的同步锁对象有什么要求?
1.对于实例方法建议使用this作为锁对象。
2.对于静态方法建议使用字节码(类名.class)对象作为锁对象。
方式二:同步方法
作用:把访问共享资源的核心方法给上锁,以此保证线程安全。
原理:每次只能一个线程进入,执行完毕以后自动解锁,其他线程才可以进来执行。
同步方法底层原理 :
1. 同步方法其实底层也是有隐式锁对象的,只是锁的范围是整个方法代码。
2.如果方法是实例方法:同步方法默认用this作为的锁对象。
3.如果方法是静态方法:同步方法默认用类名.class作为的锁对象。
方式三: LOCK锁
线程池
当前创建线程的问题
创建和销毁线程的开销是很大的,当请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能.
什么是线程池
线程池的执行流程
1. 首先判断核心线程数是否已满,如果没满,则创建一个新的核心线程来执行任务.
2.如果核心线程满了,则判断阻塞队列是否已满,如果没满,则将任务存储在这个阻塞队列
3.如果阻塞队列满了,则判断最大线程数是否已满,如果没满,则创建临时线程执行任务
4.如果最大线程数已满,则执行拒绝策略
如何创建线程池
ExecutorService executorService = new ThreadPoolExecutor(3,5,3000,TimeUnit.SECONDS,new ArrayBlockingQueue<>(3),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
线程池的核心参数
任务缓冲队列
任务拒绝策略
ExecutorService的常用方法
Executors工具类实现线程池
线程通信
进程与线程
线程的生命周期
1. 当new一个线程:处于新建状态
2.调用Start():处于执行状态RUNNABLE
3.抢到CPU的执行权,变为RUNNING状态
4.线程调用Sleep(1000),进入超时等待状态,Sleep方法结束回到执行状态
5.线程调用wait()方法,进入等待状态,直到notify()方法唤醒
6.直到run()方法结束,线程死亡