概述
一、Lock
1. 概述 Lock是JDK 1.5以后将同步和锁封装成了对象。Lock是对之前synchronized的替代。
Lock接口的实现类:互斥锁ReentrantLock 。
2. synchronized与Lock区别 synchronized对于锁的操作是隐式的;Lock锁对象是显式的。
synchronized内只有一个锁。Lock可以有多个Conditoin。
3. 语法
Lock myLock = new ReentrantLock();
myLock.lock();//获取锁
try{
//do something
}finally{
//释放锁。需要放在finally子句内,否则抛异常后,锁未被释放,其他线程则会永远被阻塞
myLock.unlock();
}
二、读写锁
1. 概述 为了提高性能,Java提供了读写锁,在读的地方使用读锁,在写的地方使用写锁,灵活控制,在一定程度上提高了程序的执行效率。
读写锁分为读锁和写锁。多个读锁不互斥,读锁与写锁互斥,写锁与写锁互斥。
Java中读写锁有个接口java.util.concurrent.locks.ReadWriteLock,也有具体的实现ReentrantReadWriteLock。
在实际开发中,最好在能用读写锁的情况下使用读写锁,而不要用普通锁,以求更好的性能。
2. 使用读写锁完成一个简单的缓存系统
public class SimpleCacheDemo{
private Map cache = new HashMap();
private ReadWriteLock rwlock = new ReentrantReadWriteLock();
public Object getData(String key){
rwlock.readLock().lock();
Object obj = null;
try{
obj = cache.get(key);
if(obj == null){
rwlock.readLock().unlock();
rolock.wirteLock().lock();
try{
if(obj == null){
obj = queryDB(key);
if(obj != null){
cache.put(key, obj);
return obj;
}
}
}finally{
rwlock.writeLock().unlock();
}
rwlock.readLock().lock();
}
}finally{
rwlock.readLock().unlock();
}
return obj;
}
//从数据库查出值
public Object queryDB(key){
//todo
return null;
}
}
三、条件变量
条件变量都实现了java.util.concurrent.locks.Condition接口,条件变量的实例化是通过一个Lock对象上调用newCondition()方法来获取的,这样,条件就和一个锁对象绑定起来了。因此,Java中的条件变量只能和锁配合使用,来控制并发程序访问竞争资源的安全。
条件变量的出现是为了更精细控制线程等待与唤醒,在Java5之前,线程的等待与唤醒依靠的是Object对象的wait()和notify()/notifyAll()方法,这样的处理不够精细。 Condition将Object监视器方法wait()、notify()、notifyAll()分解成截然不同的对象,以便通过这些对象与任意Lock实现组合使用。 对应的方法是:await()、signal() 、signalAll() 。
四、使用JDK1.5后的新特性对多生产者与多消费者示例优化
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Java线程:并发协作-生产者消费者模型
*/
public class ProducerConsumer {
public static void main(String[] args) {
Godown godown = new Godown(30);
Consumer c1 = new Consumer(50, godown);
Consumer c2 = new Consumer(20, godown);
Consumer c3 = new Consumer(30, godown);
Producer p1 = new Producer(10, godown);
Producer p2 = new Producer(10, godown);
Producer p3 = new Producer(50, godown);
Producer p4 = new Producer(10, godown);
Producer p5 = new Producer(70, godown);
c1.start();
c2.start();
c3.start();
p1.start();
p2.start();
p3.start();
p4.start();
p5.start();
}
}
/**
* 仓库
*/
class Godown {
public static final int max_size = 100; //最大库存量
public int curnum; //当前库存量
private final Lock lock = new ReentrantLock();
private final Condition connProduce = lock.newCondition();
private final Condition connConsume = lock.newCondition();
public Godown() {
}
public Godown(int curnum) {
this.curnum = curnum;
}
/**
* 生产指定数量的产品
*
* @param neednum
*/
public void produce(int neednum) {
lock.lock();
try{
//测试是否需要生产
while (neednum + curnum > max_size) {
System.out.println("要生产的产品数量" + neednum + "超过剩余库存量" + (max_size - curnum) + ",暂时不能执行生产任务!");
try {
//当前的生产线程等待
connProduce.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//满足生产条件,则进行生产,这里简单的更改当前库存量
curnum += neednum;
System.out.println("已经生产了" + neednum + "个产品,现仓储量为" + curnum);
//唤醒在此对象监视器上等待的所有消费线程
connConsume.signalAll();
}finally{
lock.unlock();
}
}
/**
* 消费指定数量的产品
*
* @param neednum
*/
public void consume(int neednum) {
lock.lock();
try{
//测试是否可消费
while (curnum < neednum) {
try {
//当前的消费线程等待
connConsume.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//满足消费条件,则进行消费,这里简单的更改当前库存量
curnum -= neednum;
System.out.println("已经消费了" + neednum + "个产品,现仓储量为" + curnum);
//唤醒在此对象监视器上等待的所有生产线程
connProduce.signalAll();
}finally{
lock.unlock();
}
}
}
/**
* 生产者
*/
class Producer extends Thread {
private int neednum; //生产产品的数量
private Godown godown; //仓库
Producer(int neednum, Godown godown) {
this.neednum = neednum;
this.godown = godown;
}
public void run() {
//生产指定数量的产品
godown.produce(neednum);
}
}
/**
* 消费者
*/
class Consumer extends Thread {
private int neednum; //生产产品的数量
private Godown godown; //仓库
Consumer(int neednum, Godown godown) {
this.neednum = neednum;
this.godown = godown;
}
public void run() {
//消费指定数量的产品
godown.consume(neednum);
}
}
最后
以上就是冷酷帅哥为你收集整理的java 多线程 条件变量_JAVA线程13 - 新特性:Lock和条件变量的全部内容,希望文章能够帮你解决java 多线程 条件变量_JAVA线程13 - 新特性:Lock和条件变量所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复