1、多线程两个很重要的概念,
同步(
互斥)和
通信
2、怎么实现同步?
加锁
3、怎么实现通信?
wait(等待)和notify(唤醒)
4、同步的目的:
使用同一个锁的代码块同时只能给一个线程使用
5、通信的目的:
实现多线程间的交互,达到线程控制的目的
6、同步的原则:多线程同时操作同一数据可能产生安全问题时需要同步;
7、同步工具:synchronized关键字、ReentrantLock,ReentrantReadWriteLock
synchronized:传统的锁 示例:http://blog.youkuaiyun.com/kuyuyingzi/article/details/43561381
ReentrantLock:相当于
synchronized关键字,提供lock和unlock方法 示例:http://blog.youkuaiyun.com/kuyuyingzi/article/details/43561517
ReentrantReadWriteLock:提供了ReentrantReadWriteLock.readLock读锁和ReentrantReadWriteLock.writeLock写锁,读锁和读锁不互斥,读锁和写锁互斥,写锁和写锁互斥 示例:http://blog.youkuaiyun.com/kuyuyingzi/article/details/43561723
synchronized和Lock的区别:synchronized可以指定锁对象,如对象、字节码,比较灵活,Lock用的锁是Lock对象本身。
8、通信工具:对象的wait和notify方法、Condition、Semaphore信号灯、CyclicBarrier关卡、CountDownLatch减数器、Exchanger 交换器
wait:当前线程等待,并释放锁资源
notify:随机唤醒一个正在等待的线程
Condition:相当于wait和notify,结合ReentrantLock使用,提供await和signal方法 示例:http://blog.youkuaiyun.com/kuyuyingzi/article/details/43561517
Semaphore:控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。提供acquire(阻塞),release(释放)方法 示例:http://blog.youkuaiyun.com/kuyuyingzi/article/details/43562423
CyclicBarrier:等待多个线程到达某个位置后继续执行,提供await方法。示例:
http://blog.youkuaiyun.com/kuyuyingzi/article/details/43562275
CountDownLatch:提供countDown(减数器减1),await(减数器减到0之前等待)方法 示例:http://blog.youkuaiyun.com/kuyuyingzi/article/details/43562199
Exchanger :交换两个线程的数据,提供exchange方法 示例:http://blog.youkuaiyun.com/kuyuyingzi/article/details/43562393
补充:
可重入:同个线程对同一个锁可重复进入,例如递归函数加锁
自旋锁:
ReentrantLock lock = new ReentrantLock();
lock.tryLock(2, TimeUnit.SECONDS);
lock.tryLock(2, TimeUnit.SECONDS);
使用tryLock实现自旋锁(Spin Lock),线程A等待线程B释放锁,在2秒内不断尝试是否能够获得锁,达到2秒后还未获得锁资源,线程A则结束运行,线程B将获得资源继续执行,死锁解除