在并发环境下,采用锁的方式来解决对共享资源的互斥访问。在Java中,锁可以分类如下两类:
获取对象锁的方式:
第一种:
如果想同时获取类锁和对象锁,也是允许的,但是在编程的过程中要注意锁嵌套导致死锁的问题。
1,正常运行完同步块,同步锁被释放。
2,运行同步代码块异常终止,同步锁也会被释放。
3,调用了同步锁所属对象的wait()方法,这个线程就会释放对象锁,进入对象的等待池中。
注:线程调用Thread.sleep或者Thread.yield方法并不释放同步锁,只是把运行的机会让给其他的线程。wait会释放同步锁。
本篇不打算举实例了,真正理解了锁机制,就能判断的出来。
对象锁
JAVA中所有的对象都有一个同步锁,每个同步锁会有一个计数器,JVM负责跟踪对象被加锁的次数,没有线程获取该对象的锁时,计数器的值为0,如果一个线程第一次对这个对象加锁,那么计数器的值就为1,之后相同的线程在获得该对象的锁时,计数都会递增的加1,如果相同的线程对此对象解锁,那么计数器就会减1,当计算器为0时,其他线程就可以获取到该对象的同步锁了,一般线程离开一个synchronized方法或者synchronized代码块计数器就会递减。获取对象锁的方式:
第一种:
public synchronized void method() {};
第二种:
Object object = new Object();
public void method() {
synchronized(object) {
//方法体
}
}
类锁
其实没有什么类锁,所谓类锁实际上就是这个类的对象的对象锁,也就是说每个类都是一个java.lang.Class对象,类锁就是这个类的类对象锁。获取类锁的方式:
第一种:synchronized (xxx.class) {}
第二种:
synchronized (Class.forName("xxx")) {...}
第三种:
public static synchronized void method(){...}
如果想同时获取类锁和对象锁,也是允许的,但是在编程的过程中要注意锁嵌套导致死锁的问题。
释放锁
如下三种方式会释放同步锁:1,正常运行完同步块,同步锁被释放。
2,运行同步代码块异常终止,同步锁也会被释放。
3,调用了同步锁所属对象的wait()方法,这个线程就会释放对象锁,进入对象的等待池中。
注:线程调用Thread.sleep或者Thread.yield方法并不释放同步锁,只是把运行的机会让给其他的线程。wait会释放同步锁。
本篇不打算举实例了,真正理解了锁机制,就能判断的出来。