Lock&Conditon实现线程间的通信

Lock

 lock比synchronized更加面向对象,在传统synchronized中锁和监视器是同一个对象。在Lock中将其分离了出来,容我一一道来。Lock是java.util.concurrent.locks中的一个顶层接口。
package com.hb;


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


public class LockTest {
	public static void main(String[] args) {


		new LockTest().init();


	}


	public void init() {
		final Outputer output = new Outputer();
		new Thread(new Runnable() {


			@Override
			public void run() {
				while (true) {
					output.output("hbbb");
				}
			}


		}).start();
		new Thread(new Runnable() {


			@Override
			public void run() {
				while (true) {
					output.output("china");
				}


			}
		}).start();
	}


	class Outputer {
		// jdk1.5的锁技术
		private Lock lock = new ReentrantLock();


		public void output(String name) {
			int len = name.length();
			lock.lock();
			try {
				for (int i = 0; i < len; i++) {
					System.out.print(name.charAt(i));
				}
				System.out.println();
			} finally {
				// 不管怎么样,拿了锁最后一定要释放,自己不放,没有人能放。
				lock.unlock();
			}


		}


	}


}

读写锁:

读写锁分为读锁和写锁,写锁和写锁互斥,写锁与读锁互斥,读锁与读锁不互斥。这是jvm自己控制的,上好对应的锁就可以了,为什么读锁与读锁不互斥呢?上锁是为了防止线程出现安全问题,多个人读而已,又不会修改数据。所以是可以的。
下面来看看一个面试题:

package com.hb;


import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


public class CacheDemo {


	/**
	 * 面试题:写一个缓存系统
	 */
	// 缓存器
	private Map<String, Object> cache = new HashMap<String, Object>();
	private ReadWriteLock rwl = new ReentrantReadWriteLock();


	public Object get(String key) {
		rwl.readLock().lock();
		Object value = null;
		try {
			value = cache.get(key);
			// 如果value为null,开闭读锁,开启写锁。
			if (value == null) {
				rwl.readLock().unlock();
				rwl.writeLock().lock();
				try {
					if (value == null) {// 怕有多余的写锁进来
						value = "abc";// 实际去queryDB
					}


				} finally {
					rwl.writeLock().unlock();
				}
				rwl.readLock().lock();
			}
		} finally {
			rwl.readLock().unlock();
		}


		return value;
	}
}


Condition

Condition可以实现线程间的通信,在等待Conditon时,可能会发生伪唤醒,应该将其定义在一个循环中等待唤醒。一个锁的内部可以有多个Condition,即有多路等待和通知,可以参考api给出的Condition演示。
package com.hb;


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


public class ConditionCommunication {


	/**
	 * 
	 * 面试题:
	 * 子线程循环10次,主线程循环20次,接着又是子线程循环10次,主线程循环20次,如此重复50次。
	 */
	public static void main(String[] args) {
	final Business b=new Business();
    new Thread(new Runnable(){


	@Override
	public void run() {
	  for(int i =1;i<=50;i++){
		b.sub1(i);
	  }
	}
	
}).start();


for(int i=1;i<=50;i++){
	b.main(i);
	}


}


//将需要同步的代码提取出来单独存在,这样可以提高代码的扩展性等。
static class Business{
	private Lock lock=new ReentrantLock();
	private Condition condition1=lock.newCondition();
	private Condition condition2=lock.newCondition();
	private boolean flag =true;
public  void sub1(int i){
//如果不是我,那就等待,由于线程存在伪唤醒的情况,所以给整个while()
	lock.lock();
	try{
		 while(!flag){
		    	try {
				    condition1.await();
				} catch (InterruptedException e) {
				
					e.printStackTrace();
				}
		    }
			for(int j =1;j<=10;j++){
				System.out.println("sub thread sequence of "+j+" ,loop of "+i);
			}
			flag=false;
			condition2.signal();
	}finally{
		lock.unlock();
	}
   
}
public   void main(int i ){
	lock.lock();
	try{
		  while(flag){
		    	try {
					condition2.await();
				} catch (InterruptedException e) {
				
					e.printStackTrace();
				}
		    }
			for(int j =1;j<=20;j++){
				System.out.println("main thread sequence of "+j+" ,loop of "+i);
			}
			flag=true;
			condition1.signal();


	}finally{
		lock.unlock();
	}
  
}
}




}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值