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

原创 2016年05月30日 22:45:56

一个线程开始执行后就进入等待,然后另外一个线程来唤醒它

代码如下:

package com.zcj.thread02;

public class Thread01 {
   private static Object object= new Object();
   public static void main(String[] args) {
	  ThreadA theA = new ThreadA(object);
	  ThreadB threadB = new ThreadB(object);
	  theA.start();
	  try {
		Thread.sleep(3000);
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	  threadB.start();
   }
}

class ThreadA extends Thread{
	private Object object;
	public ThreadA(Object object){
		this.object=object;
	}
	@Override
	public void run(){
		synchronized (object) {
			try {
				System.out.println("我开始等待。。。");
				object.wait();
				System.out.println("我被唤醒了,不再等待");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

class ThreadB extends Thread{
	private Object object;
	public ThreadB(Object object){
		this.object=object;
	}
	@Override
	public void run(){
		synchronized (object) {
				object.notify();
		}
	}
}
一个消费者和一个生产者的同步问题:

package com.zcj.thread02;

public class Thread01 {
   public int count= 0;
   public  void produce(){
	   synchronized (this) {
			if(count==1){
				try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		     }
			System.out.println("我生产商品!");
			count=1;
			this.notify();
		}
   }
   public void consumer(){
	   synchronized (this) {
		    if(count==0){
		    	try {
		    		this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		    }
		    System.out.println("我消费商品");
		    count=0;
		    this.notify();
		}
   }
   public static void main(String[] args) {
	  Thread01 thd = new Thread01();
	  ThreadA threadA = new ThreadA(thd);
	  ThreadB threadB = new ThreadB(thd);
	  threadA.start();
	  threadB.start();
   }
}

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

class ThreadB extends Thread{
	private Thread01 thd;
	public ThreadB(Thread01 thd){
		this.thd=thd;
	}
	@Override
	public void run(){
		while(true){
			thd.consumer();	
		}
	}
}

多个生产者和多个消费者的例子如下:注意其中变化的部分,while和notifyAll();不过使用synchronized有个问题就是唤醒的时候不能有所指定的唤醒对应的线程:

首先解释下这里为什么会使用while语句来判断:因为如果在用if的时候,当线程获得锁再次进入临界区就不会再去判断条件了,多个线程一起工作的时候就可能导致count的值超过1,另外在多个消费线程在消费的时候也可能导致下面count最终消费后的数量低于0,这样不就不符合逻辑了。使用notifyAll的原因是比如多个生产者和多个消费者一起工作,假如某个生产者开始等待,他唤醒的可能是另外一个生产者,这样另外一个生产者也进入等待,就存在一种情况导致消费者一直得不到唤醒,任务就进行不了了

package com.zcj.thread02;

public class Thread01 {
   public int count= 0;
   public  void produce(){
	   synchronized (this) {
			while(count==1){
				try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		     }
			System.out.println("我生产商品!");
			count=1;
			this.notifyAll();
		}
   }
   public void consumer(){
	   synchronized (this) {
		    while(count==0){
		    	try {
		    		this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		    }
		    System.out.println("我消费商品");
		    count=0;
		    this.notifyAll();
		}
   }
   public static void main(String[] args) {
	  Thread01 thd = new Thread01();
	  ThreadA threadA = new ThreadA(thd);
	  ThreadA threadA1 = new ThreadA(thd);
	  ThreadB threadB = new ThreadB(thd);
	  ThreadB threadB1 = new ThreadB(thd);
	  threadA.start();
	  threadA1.start();
	  threadB.start();
	  threadB1.start();
   }
}

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

class ThreadB extends Thread{
	private Thread01 thd;
	public ThreadB(Thread01 thd){
		this.thd=thd;
	}
	@Override
	public void run(){
		while(true){
			thd.consumer();	
		}
	}
}




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

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

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

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

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

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

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

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

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

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

生产者消费者问题分析

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

package com.work.wor01; /** * 等待唤醒机制经典实例:生产者消费者模式。 * * 当使用多个生成者线程,多个消费者线程时,会出现线程不安全的现象,即使是同步了,也不...

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

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

多线程经典案例——生产者/消费者问题的Java实现与详解

生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共...

关于网宿厦门研发中心笔试的一道PV操作题:利用java中的多线程实现生产者与消费者的同步问题

票据为同步资源:每一时刻资源池中仅存在一张可供使用的票据public class Ticket { private int ticket=-1; synchronized public void ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java多线程---等待/唤醒以及生产者消费者经典同步synchronized的实现
举报原因:
原因补充:

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