1.释放锁的操作
① 当前线程的同步方法,同步代码块执行结束
② 当前线程的同步代码块,同步方法中出现了未处理的Error或Exception,导致当前线程异常结束
③ 当前线程在同步代码块,同步方法中执行了锁对象的wait()方法,当前线程被挂起,并释放锁。
2.不会释放锁的操作
① 线程执行同步代码块或同步方法时,程序调用 Thread.sleep(),Thread.yield()方法暂停当前线程的执行。
② 线程执行同步代码块时,其他线程调用了该线程的 suspend()方法将该线程挂起,该线程不会释放锁(同步监视器)。应尽量避免使用 suspend()和resume()这样的过时来控制线程(已经过时,尽量不用)(第②了解即可)
3.死锁
当两个或更多个线程,互相等待对方想要的锁/资源时,可能会出现死锁现象,要尽量避免同步的嵌套。
代码如下:
public class DeadLock {
public static void main(String[] args) {
Object g = new Object();
Object m = new Object();
Owner s = new Owner(g,m);//卖家线程
Customer c = new Customer(g,m);//顾客线程
new Thread(s).start();
new Thread(c).start();
}
}
//卖家
class Owner implements Runnable{
private Object goods;//商品
private Object money;//钱
public Owner(Object goods, Object money) {
super();
this.goods = goods;
this.money = money;
}
@Override
public void run() {
synchronized (goods) {//锁对象是goods,要进入第一层同步代码块,需要先占有goods锁
System.out.println("先给钱");
synchronized (money) {//锁对象是money ,要进入第二层同步代码块,需要占用money锁
//因为第二层同步代码块是在第一层里面,所以此时在占用money锁时,并没有释放goods锁
System.out.println("发货");
}
}
}
}
class Customer implements Runnable{
private Object goods;
private Object money;
public Customer(Object goods, Object money) {
super();
this.goods = goods;
this.money = money;
}
@Override
public void run() {
synchronized (money) {//先要占用money锁
System.out.println("先发货");
synchronized (goods) {//接着占用goods锁
System.out.println("再给钱");
}
}
}
}