java中jdk1.5新的线程同步的解决方式Lock,condition,以及生产者消费者的示例代码详解

/*
 * jdk1.5提供了新的线程同步的解决方案,即用lock和condition实现等待唤醒机制
 * 将Synchronized替换为了lock
 * 将wait,notify替换为了condition对象
 * 将隐示的锁变为了显示的所,更加的方便快捷
 * 示例代码为生产者消费者的例子,有两个生产者,两个消费者,生产一个,消费一个
 * 代码中总共分为4大部分,代码较长,希望读者能仔细观看,一定会有收获的
 * 第一部分Resource:这一部分是这段代码的核心部分,其中定义了锁,以及等待唤醒机制
 * 第二部分Comsumer:实现Runnable接口,覆盖run方法,调用Resource中的方法,为创建线程做准备
 * 第三部分Producer:实现Runnable接口,覆盖run方法,调用Resource中的方法,为创建线程做准备
 * 第四部分主线程:创建Resource对象,并创建线程
 */
import java.util.concurrent.locks.*;
class Resource
{
	private String name;
	private int count=1;
	private boolean flag=false;//定义标记
	private Lock lock=new ReentrantLock();//定义锁
	private Condition conditionpro=lock.newCondition();//定义两个,互相唤醒对方的线程
	private Condition conditioncon=lock.newCondition();
	public void set(String name)//将商品传进来
	{
		/*
		 * ************************************************************************************************
		 * 生产者的方法函数
		 */
		lock.lock();//上锁,用完再解锁
		try
		{
			while(flag)
			{
				conditionpro.await();
			}
			this.name=name+"--"+count++;//让商品既有商品的名字,还有生产的代号
			System.out.println(Thread.currentThread().getName()+"--生产者--"+this.name);
			flag=true;//换标记,并唤醒对方的线程
			conditioncon.signal();
		}
		catch(Exception e)//将异常处理一下
		{
			System.out.println(e.toString());
		}
		finally
		{
			lock.unlock();//解锁必须放在finally中,因为上边的代码可能执行到一半,就跳出了,可能还未解锁,造成错误
		}
	}
	/*
	 * **************************************************************************************************
	 * 消费者的方法函数
	 */
		public void out()
		{
			lock.lock();
			try 
			{
				while(!flag)
				{
					conditioncon.await();
				}
				System.out.println(Thread.currentThread().getName()+"+++消费者+++"+this.name);
				flag=false;//换标记并唤醒对方的线程
				conditionpro.signal();
			}
			catch(Exception e)
			{
				System.out.println(e.toString());
			}
			finally
			{
				lock.unlock();
			}
		}
	}
/*
 * ********************************************************************************************************
 */
class Producer implements Runnable
{
	private Resource res;
	Producer(Resource res)//构造函数初始化,将资源传进来
	{
		this.res=res;
	}
	public void run()
	{
		while(true)
		{
			try
			{
				res.set("+商品+");//表示生产的东西为商品
			}
			catch(Exception e)
			{
				System.out.println(e.toString());
			}
		}
	}
}
/*
 * ********************************************************************************************************
 */
class Consumer implements Runnable
{
	private Resource res;
	Consumer (Resource res)//构造函数初始化,将资源传进来
	{
		this.res=res;
	}
	public void run()
	{
		while(true)
		{
			try
			{
				res.out();
			}
			catch(Exception e)
			{
				System.out.println(e.toString());
			}
		}
	}
}
/*
 * *******************************************************************************************************
 */
public class Locktongbu 
{
	public static void main(String[] args) 
	{
		Resource r=new Resource();
		Producer pro=new Producer(r);//就是创建线程的第二种方式而已,实现Runnable的方式
		Consumer con=new Consumer(r);
		Thread t1=new Thread(pro);
		Thread t2=new Thread(pro);
		Thread t3=new Thread(con);
		Thread t4=new Thread(con);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}

}

猜你喜欢

转载自blog.csdn.net/qq_41901915/article/details/81282632