1.线程池:
是一个可以容纳多个线程的容器。
避免反复创建线程而消耗过多的资源。
线程池本质:多个线程存在的等待序列。
为了避免每每创建的对象用完之后就要被操作系统毙掉,
然后再去新创建线程执行任务,有了线程池去存储这些线程对象,
例如ArrayList(Thread),在需要线程对象的时候,
进行Thread t = array.remve(t);线程使用完毕,回到容器
array.add(t);
2.从jdk5开始,提供了线程池这个容器。
3.线程池的实现1:
java.util.concurrent.Exeutors -->concurrent包下有Excutors类
-->用该类的newFixedThreadPool()静态方法来创建线程池,并
指定池中线程的个数,返回值是一个接口实现类ExcutorService.-->
ExecutorService -->管理内存队列,基于线程可用性调度提交的任务。
-->提供方法终结任务 shutdown()
shutdownNow()
代码分析:
1.调用工厂类的静态方法,创建线程池对象
Executors.newFixedThreadPool(3);
由于这样的方法调用返回的是一个接口实现类,要用接口来接收
-->ExecutorService es = Executors.newFixedThreadPool(3);
2.调用上面返回的接口实现类es的submit()方法提交线程任务
es.submit(); -->由于submit需要一个Runnable接口实现类作为参数
-->es.submit(new SubRunnable()) -->必要在建一个Runnable接口实现类
-->public class SubRunnable implements Runnable(){
public void run(){
//重写run方法,线程任务。
}
}
ScheduledExecutorService -->定时执行任务。
代码:ScheduledExecutorService scheduledExecutor = Executors.newScheduledExecutor(传参);
4.线程池的实现2:
利用Callable接口来实现:
-->ExecutorService es = Executors.newFixedThreadPool(3);
Future<String> f = es.submit(new SubCallable());
String s = f.get();
System.out.println(s);
-->注意要有Callable的接口实现类SubCallable存在,并重写call方法。
5.线程池的实现3: ThreadPoolExxcutor -->一般不用它而是直接用Executors工具类的newFixedThreadPool()方法。
6.实现线程安全:
- 基本数据类型->atomic
- List关系->vector(not ArrayList)
- Map关系->HashMap
7.阻塞和非阻塞
- 阻塞:申请资源不得时,被阻塞进入等待队列,直到资源被释放,才可拿到资源。
- 非阻塞:申请资源不得时,则可执行其他操作,过一段时间再来申请,直到拿到资源
8.Atomic--用于基本数据,为了防止数据的非原子性操作导致数据不一致问题。
比较交换法 -- compare and swap -- CAS算法(核心)
9.Synchonized和lock()/unlock()的区别:
参考:(参考此篇写得好的文章,闲了就读,目标是读懂理解所有内容)