关闭

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

162人阅读 评论(0) 收藏 举报
分类:

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

代码如下:

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
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:53908次
    • 积分:1729
    • 等级:
    • 排名:千里之外
    • 原创:123篇
    • 转载:14篇
    • 译文:0篇
    • 评论:5条
    最新评论