java多线程---等待/唤醒以及生产者消费者经典同步Lock的实现

原创 2016年05月31日 13:06:26

在jdk1.5并发包中引入的Lock,其主要实现重入锁,和读写锁,并且相对于synchronized原生的将锁的获取和释放显示化,并且可以提供了非阻塞的获取锁,并结合condition实现多路分之,将条件更加细化,并且比synchronized效率更高,但是在jdk1.6,对synchronized做出了很多优化,所以性能不一定比lock差,下面给出使用lock来实现等待/唤醒和之前的生产者消费者同步问题的代码:

package com.zcj.thread03;

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

public class LockTest {
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    
    public void waitTest(){
    	lock.lock();
    	try{
    		System.out.println("我开始等待,等待被唤醒!");
    		condition.await();
    		System.out.println("我已经被唤醒!");
    	}catch(InterruptedException e){
    		e.printStackTrace();
    	}finally{
    		lock.unlock();
    	}
    }
    
    public void signalTest(){
    	lock.lock();
    	System.out.println("我唤醒等待线程");
    	condition.signal();
    	lock.unlock();
    }
    
    public static void main(String[] args) {
		LockTest lockTest = new LockTest();
		ThreadA threadA = new ThreadA(lockTest);
		ThreadB threadB = new ThreadB(lockTest);
		threadA.start();
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		threadB.start();
	}
}

class ThreadA extends Thread{
	private LockTest lockTest;
	public ThreadA(LockTest lockTest){
		this.lockTest = lockTest;
	}
	@Override
	public void run(){
		lockTest.waitTest();
	}
}

class ThreadB extends Thread{
	private LockTest lockTest;
	public ThreadB(LockTest lockTest){
		this.lockTest = lockTest;
	}
	@Override
	public void run(){
		lockTest.signalTest();
	}
}
单个消费者和单个生产者的同步代码如下:

package com.zcj.thread03;

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

public class LockTest {
	private int count=1;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    
    public void produce(){
    	lock.lock();
    	try{
    		if(count==1){
    			condition.await();
    		}
    		count=1;
    		System.out.println("生产者生产商品!");
    		condition2.signal();
    	}catch(InterruptedException e){
    		e.printStackTrace();
    	}finally{
    		lock.unlock();
    	}
    }
    
    public void consume(){
    	lock.lock();
    	try{
    		if(count==0){
    			condition2.await();
    		}
    		count=0;
    		System.out.println("消费者消费商品!");
    		condition.signal();
    	}catch(InterruptedException e){
    		e.printStackTrace();
    	}finally{
    		lock.unlock();
    	}
    	
    }
    
    public static void main(String[] args) {
		LockTest lockTest = new LockTest();
		ThreadA threadA = new ThreadA(lockTest);
		ThreadB threadB = new ThreadB(lockTest);
		threadA.start();
		threadB.start();
	}
}

class ThreadA extends Thread{
	private LockTest lockTest;
	public ThreadA(LockTest lockTest){
		this.lockTest = lockTest;
	}
	@Override
	public void run(){
		
		while(true){
			lockTest.produce();
		}
	}
}

class ThreadB extends Thread{
	private LockTest lockTest;
	public ThreadB(LockTest lockTest){
		this.lockTest = lockTest;
	}
	@Override
	public void run(){
		while(true){
			lockTest.consume();
		}
	}
}
从代码中可以看出使用lock我们可以指定唤醒什么条件下的线程

接下来编写多个消费者和多个生产者,只需要把if改为while和signal改为signalAll即可,代码如下:

package com.zcj.thread03;

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

public class LockTest {
	private int count=1;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    
    public void produce(){
    	lock.lock();
    	try{
    		while(count==1){
    			condition.await();
    		}
    		count=1;
    		System.out.println(Thread.currentThread().getName()+"生产者生产商品!");
    		condition2.signalAll();
    	}catch(InterruptedException e){
    		e.printStackTrace();
    	}finally{
    		lock.unlock();
    	}
    }
    
    public void consume(){
    	lock.lock();
    	try{
    		while(count==0){
    			condition2.await();
    		}
    		count=0;
    		System.out.println(Thread.currentThread().getName()+"消费者消费商品!");
    		condition.signalAll();
    	}catch(InterruptedException e){
    		e.printStackTrace();
    	}finally{
    		lock.unlock();
    	}
    	
    }
    
    public static void main(String[] args) {
		LockTest lockTest = new LockTest();
		ThreadA threadA = new ThreadA(lockTest);
		ThreadA threadA1 = new ThreadA(lockTest);
		ThreadB threadB = new ThreadB(lockTest);
		ThreadB threadB1 = new ThreadB(lockTest);
		threadA.start();
		threadA1.start();
		threadB.start();
		threadB1.start();
	}
}

class ThreadA extends Thread{
	private LockTest lockTest;
	public ThreadA(LockTest lockTest){
		this.lockTest = lockTest;
	}
	@Override
	public void run(){
		
		while(true){
			lockTest.produce();
		}
	}
}

class ThreadB extends Thread{
	private LockTest lockTest;
	public ThreadB(LockTest lockTest){
		this.lockTest = lockTest;
	}
	@Override
	public void run(){
		while(true){
			lockTest.consume();
		}
	}
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

Java多线程-Lock锁的使用,以及生产者和消费者的实现

本文中将主要介绍Java多线程编程基础中的Lock锁对象的使用,以及如何一步一步实现Java代码的生产者与消费者; 1、Java中如何使用Lock锁以及死锁问题的描述 2、Java实现生产者...

JAVA多线程(五)用lock、synchronized、阻塞队列三种方法实现生产者消费者模式

用乐观锁、悲观锁、阻塞队列三种方法实现生产者消费者模式

Java多线程实现生产者消费者程序(Wait,Notify实现和Lock,Condition实现)

package com.daxin; import java.util.ArrayList; import java.util.Random; /** * * 生产者消费者程序 * *...
  • Dax1n
  • Dax1n
  • 2017年03月15日 14:10
  • 321

java多线程实现生产者与消费者---经典问题

前几天老师领着学习了一下单线程和多线程的题目。 这里是操作系统中非常经典的题目,生产者和消费者的题,这里涉及的是仓库, 只有一个人(生产者或消费者)进入,另一个人只有等待。 这里的重点是关于传值...

Java多线程 多个生产者和多个消费者实现同步 jdk1.4

程序说明:2个生产者,2个消费者, 生产一个商品,消费一个商品(商品有标号) 特殊:这里生产者、消费者都有多个,  1. 如果生产者、消费者都是1个,那么flag标记可以用if判断。这里有多个,...

java多线程实现生产者/消费者同步

问题:主进程开两条线程,一条线程生产,一条线程消费。要求生产者不能过度生产,即生产的产品有数量上限,假定就是5个,消费者不能过度消费,即不能没有了产品也在消费 。 Buffer类,用作缓冲区 ...

多线程——等待唤醒机制经典实例:生产者消费者模式

package com.qianfeng.demo04; /** * 。 * */ //资源 class Resource{ private String name; private int ...

多线程-等待唤醒机制经典案例-生产者消费者

生产者消费者问题分析

多线程——等待唤醒机制经典实例:生产者消费者模式(优化)

package com.work.wor01; /** * 等待唤醒机制经典实例:生产者消费者模式。 * * 当使用多个生成者线程,多个消费者线程时,会出现线程不安全的现象,即使是同步了,也不...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java多线程---等待/唤醒以及生产者消费者经典同步Lock的实现
举报原因:
原因补充:

(最多只允许输入30个字)