Synchronized锁,是挂在对象头上的,对象头Threadid标识获得锁的线程
线程加锁—>对象的Threadid标识符 = 对应的线程id—>其他线程访问时,拒绝
线程释放锁—> 对象的Threadid标识符 = null —> 其他线程可以访问
线程上锁
程序执行Synchronized修饰的代码范围内,给对象上锁
线程自动释放锁
程序执行Synchronized修饰的代码范围外,会自动释放锁
Synchronized 修饰方法时,方法执行完后会自动释放锁
Synchronized 修饰块时,代码块执行完后会自动释放锁
Wait 使用,手动释放锁
使用wait释放锁,并挂起,需要notify/notifyAll唤醒
当线程需要等待满足条件,才能继续执行时,可以使用wait+notify组合
某个线程一直扣除血量
for(int i=0;i<101;i++){
synchronized(data){data.count--;data.notify();System.out.println("血量-1");
}
}
某个线程等待血量低于20时,输出血量值提醒
//等待血量 不足20时,输出血量通知 synchronized(data){while(data.count>=20){try {data.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("当前血量不足剩余值为:"+data.count+"请及时补充");}
Wait 方法:释放对象锁,当前线程挂起,被 唤醒并获得锁后 从下一条语句开始执行
Notify 方法:仅唤醒一个挂起的线程,等代码出了synchronized的修饰代码时自动释放锁,被唤醒的线程获得锁。若有一个wait的线程,另外的线程并未发起notify的话,则该wait线程一直处于wait状态
NotifyAll 方法:仅唤醒所有挂起的线程,线程争夺锁
此外,以上方法属于对象方法,只能在Synchronized代码块下使用