1 创建线程
extends Threadimplements Runnable
启动线程:threadl类的start()
线程完成:1、run()方法执行完成;2、抛出一个未处理的异常导致线程的提前结束
2 线程的状态
新创建 线程被创建,但是没有调用start方法
可运行(RUNNABLE) 运行状态,由cpu决定是不是正在运行
被阻塞(BLOCKING) 阻塞,线程被阻塞于锁
等待/计时等待(WAITING) 等待某些条件成熟
被终止 线程执行完毕
3 线程的常用方法
run()和start()
run就是一个普通的方法,跟其他类的实例方法没有任何区别。
Sleep()
不会释放锁,所以我们在用sleep时,要把sleep放在同步代码块的外面。
yield()
当前线程出让cpu占有权,当前线程变成了可运行状态,下一时刻仍然可能被cpu选中,不会释放锁。
wait()和 notify()/notiyfAll()
调用以前,当前线程必须要持有锁,调用了wait() notify()/notiyfAll()会释放锁。
join() 结合 线程池可以保证 线程的顺序执行ExecutorService executor = Executors.newSingleThreadExecutor();
4 线程间协作和通信
Synchronized关键字只能修饰代码块和方法,当修饰的是静态方法时锁住整个类。原子性和可见性。
volatile 关键字 只保证线程可见性,应用场景单例模式的双重校验锁。适合读多写少的场景。
等待通知机制
等待超时模式
5 并发容器和并发工具类
ConcurrentHashMap分段锁实现多线程安全。ConcurrentSkipListMap TreeMap的并发实现
ConcurrentSkipListSet TreeSet的并发实现
SkipList跳表
ConcurrentLinkedQueue 无界非阻塞队列CopyOnWriteArrayList和CopyOnWriteArraySet 写的时候进行复制,可以进行并发的读。
ArrayBlockingQueue: 数组结构组成有界阻塞队列。
先进先出原则,初始化必须传大小,take和put时候用的同一把锁
LinkedBlockingQueue:链表结构组成的有界阻塞队列
先进先出原则,初始化可以不传大小,put,take锁分离
并发工具类
CountDownLatch
CyclicBarrier
控制并发线程数的Semaphore
Exchanger
6 Executor框架的结构
1.任务的产生:Runnable接口和Callable接口
这2个对象属于任务对象。工具类Executors可以把一个Runnable对象封装为Callable对象。当我们拥有任务对象之后,就可以将其交给ExecutorService(Executor的一个实现接口)了,这样转入第二部分–任务处理部分。
2.任务的处理:Executor接口—>ExecutorService接口
任务的处理主要是将任务丢到线程池中,由线程池提供线程将任务“消费掉”。
线程池有2类:ThreadPoolExecutor和ScheduledThreadPoolExecutor。2种线程池类均可以通过工厂类Executors来创建。
3.任务结果的获取:Future接口 或者通过CompletionService来保存返回值(结果存在阻塞队列中)
参考:https://www.cnblogs.com/MOBIN/p/5436482.html
参考:http://blog.csdn.net/qq_16811963/article/details/52161713