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

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

代码如下:

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();	
		}
	}
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值