Java 锁Lock实例使用
synchronized和Lock区别:
synchronized:
(如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁)
获取锁的线程释放锁情况:
1、获取锁的线程执行完了该代码块,然后线程释放对锁的占有。
2、线程执行发生异常,此时JVM会让线程自动释放锁。
3、这个主要是在等待唤醒机制里面的wait()方法,在等待的时候立即释放锁,方便其他的线程使用锁。而且被唤醒时,就在此处唤醒。
虽然我们可以理解同步代码块和同步方法的锁对象问题,但是我们并没有直接看到在哪里加上了锁,在哪里释放了锁,同时为了更好地释放锁。
锁对象Lock:
(通过Lock可以知道线程有没有成功获取到锁。这个是synchronized无法办到的)
1、Lock不是Java语言内置的,synchronized是Java语言的关键字,因此是内置特性。Lock是一个类,通过这个类可以实现同步访问。
2、synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中。
3、在资源竞争不是很激烈的情况下,synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,synchronized的性能会下降几十倍。
Lock使用简单示例:(卖火车票例子)
package code;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* sellTicket.java
* @author 董欣欣
* @date 2017年4月9日 上午8:55:04
*/
public class sellTicket implements Runnable{
private static int num=30;
private Lock lock=new ReentrantLock();
@Override
public void run() {
// TODO Auto-generated method stub
while(num>0){
try{
lock.lock();
if(num>0){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售"+num--);
}
}finally{
lock.unlock();
}
}
}
}
package code;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
*
* sellTicket.java
* @author 董欣欣
* @date 2017年4月9日 上午8:55:04
*/
public class sellTicket implements Runnable{
private static int num=30;
private Lock lock=new ReentrantLock();
@Override
public void run() {
// TODO Auto-generated method stub
while(num>0){
try{
lock.lock();
if(num>0){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在出售"+num--);
}
}finally{
lock.unlock();
}
}
}
}
测试方法:
public static void main(String args[]) {
sellTicket str = new sellTicket();
Thread tr1 = new Thread(str, "窗口1");
Thread tr2 = new Thread(str, "窗口2");
Thread tr3 = new Thread(str, "窗口3");
tr1.start();
tr2.start();
tr3.start();
}
public static void main(String args[]) {
sellTicket str = new sellTicket();
Thread tr1 = new Thread(str, "窗口1");
Thread tr2 = new Thread(str, "窗口2");
Thread tr3 = new Thread(str, "窗口3");
tr1.start();
tr2.start();
tr3.start();
}