线程通信
推荐文章
通信方式
- 共享对象
- wait notify 和 notifyAll机制 (并发包中的Condition)
注意点
- 不要在字符串常量或全局对象中调用wait(),因为可能调用notify或notifyAll的时候
不知道唤醒了哪一个,或者为什么都唤醒了?因为多个引用指向的是同一个对象! - 丢失信号:如果一个线程先于被通知线程调用wait()前调用了notify(),等待的线程将错过这个信号。
可以通过将信号保存在信号类,就是通过一个变量来记录这个信号,如果notify , 置为true , wait –> false;
Synchronized
synchronized真的是一个见过n遍的关键字,可以说只要提到多线程就会想到它;
可是,
什么时候要考虑同步?
多个线程对同一个(注意是同一个)资源进行操作(修改),这样就构成了一种竞争,
这时我们就必须保证线程A对资源的修改对线程B是可见的,也就是说,线程B不会一会
读到这个数据,一会这个数据就变了.
典型的就是生产者和消费者,它们的共享资源就是存放物品的篮子,生产者往里面放,消费者
往里面拿,这时,我们要做就是对篮子的操作进行同步!使同一个时刻只有一个线程具有篮子的使用
权限!
所以,一句话总结:同一个时刻,只有一个线程具有共享资源的锁;怎么用它?
比如:线程A , B ; 共享对象 S非静态方法
- 在方法上加锁
如果线程A不退出加锁方法的话,线程B只要调用S中的同步方法就会被阻塞(非同步方法可以调用)
因为S的锁被A占用着,B也想或得S的锁 ;
- synchronized(object) 代码块
这种方法线程获得就是你放入的Object的锁,比如 Object= this,那么它锁住的就是当前调用的对象!
这种方法粒度更小,只会同步代码块,方法的其他部分任意线程都可以同时访问,退出代码块也就会释放锁
- synchronized(object) 代码块
- 在方法上加锁
静态方法
同样也是两种方式,但是它所不同的时,调用静态方法,你锁住的就是整个类对象 S.class;