使用Lock实现多线程同步

Java JDK1.5增加了一个新特性Lock和Conndition接口,Lock对象代替了synchronized同步代码,将同步代码快中的锁对象换成了Condition对象。

一个同步代码块只有一个锁对象对应,如果需要两个锁对象的话就需要再加一个同步代码块,这样就容易产生死锁。

使用了Lock和Condition的话,将锁对象的wait,notify和notifyAll替换成了Condition对象的await,signal。

这样就不需要使用多个同步代码块而且可以唤醒指定的线程。

以消费者和生产者为例来演示一下。两个生产者和两个消费者,实现交替运行,即生产一个商品就消费一个商品,不能出现连续生产两个商品或者连续消费两个商品:


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class Resources {
	private static Resources mRes = null;
	private String mName;
	private boolean mFlag = false;
	private int mNumber = 1;
	private final ReentrantLock locker = new ReentrantLock();
	private final Condition productCondition = locker.newCondition();
	private final Condition consumerCondition = locker.newCondition();

	private Resources() {
	}

	public static Resources getInstance() {
		if (mRes == null) {
			synchronized (Resources.class) {
				if (mRes == null) {
					mRes = new Resources();
				}
			}
		}

		return mRes;
	}

	public void set(String name) {
		locker.lock();
		
		try{
			// 如果已经生成了一个商品,就等待消费者消费
			while (mFlag) {
				try {
					productCondition.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			mName = name + "--" + mNumber++;
			System.out.println(Thread.currentThread().getName() + "---------生成者: "
					+ mName);
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			mFlag = true;
			consumerCondition.signal();;
		}finally{
			locker.unlock();
		}
	}

	public void out() {
		locker.lock();
		try{
			// 如果消费了商品后,就等待生产者生成
			while (!mFlag) {
				try {
					consumerCondition.await();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			System.out.println(Thread.currentThread().getName() + "消费者: " + mName);
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			mFlag = false;
			productCondition.signal();
		}finally{
			locker.unlock();
		}
	}
}

class Product implements Runnable {
	public void run() {
		Resources res = Resources.getInstance();
		while (true)
			res.set("--------------商品----");
	}
}

class Consumer implements Runnable {
	public void run() {
		Resources res = Resources.getInstance();
		while (true)
			res.out();
	}
}

public class Main {

	public static void main(String[] args) {
		Product p = new Product();
		Consumer c = new Consumer();

		new Thread(p).start();
		new Thread(p).start();
		new Thread(c).start();
		new Thread(c).start();
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值