(
多线程同时访问同一块资源的话,会导致结果错误。所以有了同步这个概念。同步,顾名思义就是,多个线程其他地方和一起做一件事,但在
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主线程