线程优化
线程的优化:线程池
原因
每一个线程大约占1mb的内存,但是线程的回收却需要等到run方法中的代码执行完毕后,等待GC回收
因为线程和线程任务可以分离,那么当一个线程执行完一个线程任务后,能不能使其执行下一个线程任务(线程的复用)
线程池是什么?
一个存放线程的容器
线程池的优点
可以帮助我们管理线程,包括但不限于线程的创建,销毁,复用等
线程池的体系
Executor:线程池的顶级
方法:
void execute (Runnable command);提交线程所需执行的任务
子接口:
ExecutorService
方法:
void shutdown();关闭线程池
boolean isShutdown();判断线程池是否关闭
<T> Future<T> submit(Callable<T> task);提交任务
<T> Future<T> submit(Runnable task, T result);提交任务
ScheduledExecutorService
方法:
public ScheduledFuture<?> schedule(Runnable command,long delay, TimeUnit unit);
延迟多长时间后执行该任务
Runnable command:要执行的任务
long delay 延期时间单位
TimeUnit unit 延期时间的单位
public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit);
延迟多久后,间隔多久重复执行任务
Runnable command:要执行的任务
long initialDelay 延期时间单位
long period 重复间隔执行时间
TimeUnit unit 延期时间的单位
long period:前一次任务开始时间,与下一次任务开始时间的间隔
特殊情况:前一次执行任务时间大于间隔时间,则也会等待运行完后再重复
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit);
Runnable command:要执行的任务
long initialDelay 延期时间单位
long delay 重复间隔执行时间
TimeUnit unit 延期时间的单位
long delay:前一次任务结束时间,与下一次任务开始时间的间隔
如何创建线程池 Executors
固定线程池:
特点:线程池中线程数量固定
Executors.newFixedThreadPool(nThreads);
//(nThreads)是固定几条线程
注:该线程池的线程是前台线程
固定线程池关闭时,需要等待所有任务执行完毕后才会关闭
ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
注:该线程池的线程是前台线程
需要等待所有任务执行完毕后才会关闭;
可变线程池:
特点:线程池中线程数量不固定
需要等待所有任务执行完毕后才会关闭;
单例线程池:
特点:线程池中只有一个线程
ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
需要等待所有任务执行完毕后才会关闭;
调度线程池:
特点:间隔(按照开始/结束时间/延迟一段时间后再次执行一次线程任务
ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(corePoolSize[数量]);
当关闭线程池时,不管任务是否执行完毕,都会关闭线程池.
延迟线程池:
单例延迟线程池(了解):
特点:线程池中只有一个线程,延迟多久后执行
ScheduledExecutorService newSingleThreadScheduledExecutor= Executors.newSingleThreadScheduledExecutor();
抢占线程池(了解):
特点:多个线程可以执行一个任务,处理较为耗时的任务,1.8出现的,窃取算法
线程任务的优化:回调
callable接口
与runnable的区别
1.callable有返回值的,重写call方法,call方法有异常的声明,只能使用线程池对象使用
2.Runnable没有返回值,重写run方法,run方法没有异常声明,可以使用thread
callable接口的方法
get(); //获取返回值,并且会堵塞当前的线程,直到获取到返回值
锁的优化:Lock
原因
synchronized的使用不够方便,不够灵活,所以对其进行了优化
体系
lock
方法:
void lock(); //上锁
boolean tryLock(); //判断是否上锁了
void unlock(); //释放锁
子类:
ReentrantLock //重入锁
ReentrantReadWriteLock //重读锁