util.Concurrent-Lock&Condition处理线程访问共享资源的安全问题

Java5对共享资源访问的解决方案:

1个锁上绑定多个监视器

package thread.lock;

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

/**
 * 使用Java5新的共享资源处理方式
 * Lock
 * Condition
 * 
 * 最大的不同:1个锁上可以绑定多个监视器!
 * 让线程的等待与唤醒更明确
 */
public class TwoThreadsCommunication {
	
	
	public static void main(String[] args) {
		
		new TwoThreadsCommunication().justDoIt();
		
	}
	
	public void justDoIt() {
		
		final ResourceHandler r = new ResourceHandler();
		
		
		new Thread(new Runnable() {
			public void run() {
				for(int i=0;i<100;i++)
					r.produce();
			}
		}, "线程A").start();
		
		new Thread(new Runnable() {
			public void run() {
				for(int i=0;i<100;i++)
					r.consume();
			}
		}, "线程B").start();
	}
	
	
	/**
	 * 资源类
	 * 使用Java5新增的处理资源共享的锁机制
	 */
	class ResourceHandler {
		//synchronized -> lock
		//wait() -> await(), notify() -> signal(), notifyAll() -> signalAll()
		
		final Lock lock = new ReentrantLock();//唯一锁 
		
		//创建与lock绑定的不同Condition
		final Condition con_produce = lock.newCondition();//生产者在lock锁上的监视器 
		final Condition con_consume = lock.newCondition();//消费者在lock锁上的监视器
		
		//状态变量在资源内部进行操作
		private boolean full;
		
		//生产线程操作共享资源的方法
		public void produce() {
			//加锁
			lock.lock();
			
			try {
				//notice: 这里用while,不要用if。可防止死锁!
				while(full) {
					try {
						con_produce.await();/**生产者等待*/
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				for(int i=1;i<=10;i++) {
					System.out.println(Thread.currentThread().getName()+" run***" + i);
				}
				full = true;
				con_consume.signal();/**唤醒消费者*/
			} finally {
				//释放锁
				lock.unlock();
			}
		}
		
		//消费线程操作共享资源的方法
		public void consume() {
			//加锁
			lock.lock();
			
			try {
				//notice: 这里用while,不要用if。可防止死锁!
				while(!full) {
					try {
						con_consume.await();/**消费者等待*/
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				for(int j=1;j<=10;j++) {
					System.out.println(Thread.currentThread().getName()+" run******" + j);
				}
				full = false;
				con_produce.signal();/**唤醒生产者*/
			} finally {
				lock.unlock();
			}
		}
		
	}
}

猜你喜欢

转载自just2learn.iteye.com/blog/2070638
今日推荐