java回顾之线程池、死锁、等待唤醒机制
一、线程池
1.1线程池的思想
就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源
1.2线程池的好处
1、降低资源消耗
2、提高响应速度
3、提高线程的可管理性
1.3、线程池的使用
创建对象:
Executors的方法:
public static ExecutorService newFixedThreadPool(int nThreads) :返回线程池对象。
(参数表示线程个数最大数量)
ExecutorService的方法:
public Future<?> submit(Runnable task) :执行一个任务
返回值Future接口:用来记录线程任务执行完毕后产生的结果。
二、死锁
在多个线程执行中,如果有多个锁,线程获取到了部分的锁,不释放手中的锁,一直等待剩余的其他锁,导致线程互相进入等待状态,造成每个线程都无法执行。
synchronized("字符") synchronized锁里面的对象如果相同的话,即使不在一个类里,也是同一个锁
如上图所示,一共有两个锁,两个线程,每个线程只有拿到两个锁,才可以完成全部,当一号拿到左筷子时,二号拿了右筷子,这样就成了死锁,线程都出不来
三、线程状态
NEW : 新建状态。 创建出线程对象时
Runnable:可运行状态。 调用了start()方法时
Blocked :锁阻塞状态。 在等待锁的时
Waiting :无限等待状态。 在调用wait()时
Timed Waiting :计时等待状态。 在调用sleep(long times)时
Terminated:被终止状态。 在run()方法执行结束时
新建、运行、锁阻塞、等待、睡眠、终止。
四、等待唤醒机制
Object类的方法
wait() 让当前线程进入等待状态
notify() 唤醒一个正在等待的进程
这两个方法必须使用锁对象调用
两个方法的注意事项
两个方法为什么要定义在Object类中
因为方法需要锁对象来调用,锁对象可以是任何类型,为了避免转型,所以定义在Object类中
两个方法必须卸载同步里面吗?
在同步里面才有锁这个概念,在同步外面对象已经失去了锁的概念
wait()等待和sleep()睡眠的区别
等待会释放锁,等待别的线程过来!!!!!
如果有交替进行的需求,可以定义一个flag每个线程走完改一下值,flag=1是一个线程执行,flag=2另一个线程执行
六、定时器
构造方法:
public Timer():构造一个定时器
常用方法:
void schedule(TimerTask task, long delay)
//在指定的延迟之后安排指定的任务执行。
void schedule(TimerTask task, long delay, long period)
//在指定 的延迟之后开始,重新执行固定延迟执行的指定任务。
void schedule(TimerTask task, Date time)
//在指定的时间安排指定的任务执行。
void schedule(TimerTask task, Date firstTime, long period)
//从指定的时间开始,对指定的任务执行重复 的 固定延迟执行 。