多线程之Lock接口
上一篇文章讲述了多线程的概念和同步代码块来解决多线程造成的问题。
https://mp.csdn.net/postedit/102060855
如果想要解决多线程访问多行代码涉及操作同一变脸造成的问题时,在JDK1.5之后推出了新的API来解决这个问题。
就是Lock接口
将上一篇文章里的synchronize替换为Lock
package com.evan.counter;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Test {
public static void main(String[] args) {
Resource resource = new Resource();
MyRunnable runnable = new MyRunnable(resource);
Thread t1 = new Thread(runnable);
Thread t2 = new Thread(runnable);
Thread t3 = new Thread(runnable);
Thread t4 = new Thread(runnable);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resource{
private int count = 100;
private Lock lock = new ReentrantLock();
public void mute() {
try {
lock.lock();
if(count > 0) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
count--;
System.out.println("Count: " + count);
}
}catch(Exception e) {
}finally {
lock.unlock();
}
}
}
class MyRunnable implements Runnable{
private Resource resource;
public MyRunnable(Resource resource) {
super();
this.resource = resource;
}
@Override
public void run() {
//要执行的代码
while(true) {
resource.mute();
}
}
}
Lock接口的常用方法:
- lock() 获取锁,并锁定。
- tryLock() 在调用时,如果没有现成使用锁,再获取锁,效率稍高。
- unlock() 释放锁。
- newCondition() 获取监视器(可以指定某个现成进行wait操作或者notify操作)
- isFair() 获取是否是公平锁。
synchronize关键字 和 lock接口的区别
类别 | synchronized | Lock |
---|---|---|
存在层次 | Java的关键字,在jvm层面上 | 是一个类 |
锁的释放 | 1、以获取锁的线程执行完同步代码,释放锁 2、线程执行发生异常,jvm会让线程释放锁 | 在finally中必须释放锁,不然容易造成线程死锁 |
锁的获取 | 假设A线程获得锁,B线程等待。如果A线程阻塞,B线程会一直等待 | 分情况而定,Lock有多个锁获取的方式,具体下面会说道,大致就是可以尝试获得锁,线程可以不用一直等待 |
锁状态 | 无法判断 | 可以判断 |
锁类型 | 可重入 不可中断 非公平 | 可重入 可判断 可公平(两者皆可) |
性能 | 少量同步 | 大量同步 |