这个关键字是对对象或者类加锁,所谓对对象加锁,我现在终于理解了,这个锁针对的是引用指向的那块对象内存,并不是指引用(对象的不同别名)所以一旦在两个runnable类中的run方法中此关键字搭配上这个对象类的不同引用时,如果两个引用都指向同一个对象,则两个runnable对象的run方法是对这个对象的锁互斥的 同步访问这个对象。而且注意锁是对象锁的另一层意思
:一旦一个线程获得了对象锁,执行对象的同步代码,其他要访问执行这个对象的同步代码(这个同步代码可能与前一个线程的同步代码不同哦)线程就会因为拿不到对象锁而变为阻塞状态。只要线程拿到对象锁,其他要访问对象的线程就会进入阻塞状态
`package com.consumerandproductor;
public class Consumer implements Runnable {
private Resource myResources=null;
public Consumer(Resource myResources) {
this.myResources = myResources;
}
@Override
public void run() {
int count=0;
while (true){
synchronized (this.myResources){//理解:第一:同步代码块保证了多线程对一个代码块整体只会有一个
// 线程访问执行;第二:对象锁是行级代码级别的,也就是说未加synchronized关键字
// 之前,一个线程一次获得的对象锁是一行代码,每执行一行代码就会有可能释放锁,让别的线程有机
// 会抢到对象锁,但是有时候,我们需要一个线程完整的执行多行代码以完成一个功能,这时候就需要
//synchronized关键字来声明线程要拿到的锁属于哪一个对象或者类(静态),并使用{}将多行代码框
// 起来,这时这个代码块就具有了原子性,一个线程必须把代码块中这些行代码全部执行完毕之后才会
// 有可能释放拿到的锁,这就保证了功能的完整性何准确性,不会因为执行了一行或者多行代码后线程
// 突然释放了锁,后面再拿到锁接着执行后续的一行或多行代码,这个功能就被强行断开了,对于数据
//操作就不具有一致性了,就会发生操作造成数据出错的现象。
if (this.myResources==null){
break;
}
if (this.myResources.isProduced()) {
this.myResources.consum();
System.out.println("消费了:"+(++count)+"次");
}
if (count==50) {
break;
}
this.myResources.notify();
try {
this.myResources.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
`