一、Callable接口
1.实现Callable接口:
(1)Thread类与Runnable接口实现多线程的缺点:
1) 没有返回值;
2) 不支持泛型;
3) 异常必须处理;
(2)Callable接口实现多线程的好处:
1) Future 接 口 位 于 java.util.concurrent 包 中 ,可 以 对 具 体Runnable、Callable 任务的执行结果进行取消(cancel 方法,尝试取消执行此任务)、查询是否完成(isDone 方法)、获取结果(get 方法,等待完成,然后检索其结果)等。
2) FutrueTask 是 Futrue 接口的唯一的实现类;
3) FutureTask 同时实现了 Runnable, Future 接口。它既可以作为 Runnable 被线程执行,又可以作为 Future 得到Callable 的返回值。
(3)实现步骤:
1)创建线程任务
2)创建一个资源管理器,实现RunnableFuture接口,RunnableFuture是Future与Runnable的子接口。
3)启动线程;
4)获得取值范围;
5)判断任务是否执行结束。
代码截图 结果二、线程同步Lock锁
1.Lock锁:
(1)实现线程同步的方式:
1)synchronize方法:
2)synchronize代码块;
3)Lock代码块;
(2)Lock与synchronize的区别:
1)Lock是显示锁,synchronize是隐式锁。
2)Lock只有代码锁,synchronize有代码块锁和方法锁;
3) 使用 Lock 锁,JVM 将花费较少的时间来调度线程,性能更好,并且具有更好的扩展性。
4) Lock 确保当一个线程位于代码的临界区时,另一个线程不进入临界区。如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。lock()方法会对 Lock 实例对象进行加锁,因此所有对该对象调用 lock()方法的线程都会被阻塞,直到该 Lock 对象的 unlock()方法被调用。
(3)步骤:
1)创建Lock对象;
2)调用lock()方法上锁;
3)调用unlock()方法解锁;
代码截图 结果2.线程池:
(1)什么是线程池?
1)创建对象:需要分配内存等资源。
2)销毁对象 :虽然不需要程序员操心,但是垃圾回收器会在后台一直跟踪并销毁;
对于经常创建和销毁、使用量特别大的资源,比如并发情况下的线程,对性能影响很大。
3)思路 :创建好多个线程,放入线程池中,使用时直接获取引用,不使用时放回池中。可以避免频繁创建销毁、实现重复利用。
(2)线程池的好处:
1)提高响应速度(减少了创建新线程的时间);
2)降低资源消耗(重复利用线程池中线程,不需要每次都创建);
3)提高线程的可管理性:避免线程无限制创建、从而销毁系统资源,降低系统稳定性,甚至内存溢出或者 CPU 耗尽。
(3)应用场合:
1)需要大量线程,并且完成任务的时间短;
2)对性能要求苛刻;
3)接受突发性的大量请求。
代码截图 结果3.任务调度:
(1)什么是任务调度?
任务:就是事情
调度:在不同的时间点或者在指定的时间点或者间隔多长时
间我去运行这个任务。
(2)相关类:java.util.Timer类。
(3)实例:实现时间的动态刷新。
代码截图 结果三、ThreadLocal
1.ThreadLocal类:
ThreadLocal 直译为“本地线程”,其实它就是一容器,用于存放线程的局部变量。
作用:为解决多线程程序的并发问题
构造方法:
1)ThreadLocal():创建一个线程本地变量。
常用方法:
1)set(T value):将此线程局部变量的当前线程副本中的值设置为指定值。
2.)get():返回此线程局部变量的当前线程副本中的值。
3)initialValue():返回此线程局部变量的当前线程的“初始值”。
4)remove():移除此线程局部变量当前线程的值。
案例:实现一个序列号的生成器程序。
自定义Sequence接口 通过Runnable接口实现多线程(1)未使用ThreadLocal :
代码截图 结果(2)使用ThreadLocal :
代码截图 结果2.ThreadLocal 的使用场景:
用来解决数据库连接、Session管理等。
网友评论