多线程同步 synchronized 以及wait notify notigyAll的总结

来源:互联网 发布:郑和宝船 知乎 编辑:程序博客网 时间:2024/05/14 11:54
 
(多线程同时访问同一块资源的话,会导致结果错误。所以有了同步这个概念。同步,顾名思义就是,多个线程其他地方和一起做一件事,但在synchronized标记的地方必须排队,一个一个来执行,为了实现这样的功能,又引入了锁的概念。其实synchronized就是加锁的意思,线程进去前把门锁上,其他线程进不来,办完事儿了,再开门把锁还回去。)
synchronized其实就是操作锁,锁分为两类,对象锁和类锁。
synchronized可修饰方法和代码块
1)public   synchronized void syn1(){}    //相当于当前对象的对象锁
2)byte[] aa = new byte[0];
   synchronized (aa) {}  //aa可以是任意对象 或者类的锁

如果修饰普通方法,则为对象锁
如果修饰static方法 则为类锁
aa是对象 则是对象锁
aa为类如 XXX.class 则为类锁

深入理解:多线程中,一个线程执行synchronized标记的代码,拿到了某一个锁(对象锁或者类锁),其他线程如果也想执行和这个锁有关的synchronized代码,那么必须要排队等上一个线程执行完。

具体体现:同一个类里面,如果有两个非static方法A,B都标记了synchronized,则线程1进去了A方法,同时线程2就不能进入B方法


wait notify notigyAll属于类或者对象的方法,这三个方法事都必须在synchronized里面才能调用,而且必须为同一个锁内,否则报错

wait:在拿到一个锁后,进入进入等待状态 ,并且释放锁(必须等其他进入同一个锁的线程notify notigyAll唤起
notify:在拿到一个锁后,唤醒当前锁内wait最早的线程,让他们起来排队,自己继续。
notigyAll:在拿到一个锁后,唤醒当前锁内所有wait的线程,顺序是最后wait的先运行,让他们起来排队,自己继续。

报错的例子:
byte[] aa = new byte[0];
   synchronized (aa) {
    aa.wait();//线程1在aa对象锁里 wait了
}

//同一个类的另外一个方法
public   synchronized void syn1(aa){
 aa.notify()// 线程2 想在这里唤醒aa对象锁里的线程 报错了,因为这个synchronized 方法拿到的不是aa对象锁而是 这个方法所在类的对象锁--this

实际应用:主线程wait,然后多个子线程执行完任务后notify主线程
0 0
原创粉丝点击