多线程:
创建多线程;
Thread
自己new Thread()并调用start方法。
Runnable
将执行过程和线程对象分离,以便得到清晰的设计结构,和复用runnbale对象。
线程池
不用创建和管理线程。往里面丢入Runnbale或Callable即可。Callable还可以异步拿到处理后的结果。
线程共享数据
ThreadLocal:线程内共享数据。
锁:线程间共享数据,这时需要同步,否则会出现错误数据或脏数据。
线程间同步
锁
synchronized
可以把任何对象拿来当锁用,比如:类的字节码对象、this、任何类型的Object对象。
它只是线程之间的简单互斥,不管线程要对资源做什么操作。
不能交叉加锁和释放锁,例如:获取节点 A 的锁,然后再获取节点 B 的锁,然后释放 A 并获取 C,然后释放 B 并获取 D,依此类推
ReentrantLock
可以完全代替synchronized,只是使用上多了一个释放锁的动作要做。
而且更强大:
1.可以设置锁倾向于将访问权授予等待时间最长的线程,但总体吞吐量很慢。
2.可以递归上锁(即重入),但有极限,且要成对释放锁。
ReentrantReadWriteLock
又比ReentrantLock更强大
1.读-写锁允许对共享数据进行更高级别的并发访问
2.可以将锁进一步细分为读写锁。
3.写锁同ReentrantLock一样可以重入,但读锁不行。
线程间通信
wait()和notify()
被用做锁的Object(即任何对象)对象的wait()和notify()方法可实现多线程间,简单的是与否的通信。
Condition
比wait、notify更强大
1.可从一把锁上延伸出多个条件,让多线程间更细粒度的使用资源。即即使获取了锁权限也可以根据条件来相互间有礼貌的阻塞。
Semaphore信号灯
控制同一时间可以有几个线程访问资源。
单个信号量时可以实现互斥锁的功能,神奇的是可以由一个线程获得“锁”,再由另一个线程释放“锁”。
CyclicBarrier
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点。可以重用
CountDownLatch
在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
Exchanger
两个线程交换数据。
Thread
实例方法join(),调用者会等待此线程实例执行完。
静态方法yield().当前线程主动退出cpu调度,等待下一次被调度。
静态方法sleep().当前线程睡眠一段时间(不释放锁),再等待下一次被调度。