码迷,mamicode.com
首页 > 编程语言 > 详细

Java---19---多线程:生产者和消费者

时间:2015-01-19 17:15:55      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:多线程   安全   同步   thread   myeclipse   

生产者和消费者问题是多线程通信的经典问题。这类问题描述了这样一种情况:假设有一个仓库,用来存储产品,有生产者负责生产产品,有消费者负责消费。生产者生产的产品存放在仓库之中,消费者从仓库之中取出产品。显然这是一个同步问题,生产者和消费者共享同一资源,并且生产者和消费者之间彼此依赖,互为条件向前推进。那么,该如何编写代码来实现呢?


class Resource {
	private String name;
	private String sex;
	private boolean flag = false;

	public synchronized void set(String name, String sex) {
		if (flag == true) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.name = name + "--" + sex;
		System.out.println(Thread.currentThread().getName() + "--生产者--"
				+ this.name);
		flag = true;
		notify();
	}

	public synchronized void out() {
		if (flag == false) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println(Thread.currentThread().getName() + "---消费者---"
				+ this.name);
		flag = false;
		notify();
	}
}

class Producer implements Runnable {
	private Resource resource;
	private int num = 0;

	Producer(Resource resource) {
		this.resource = resource;
	}

	public void run() {
		while (true) {
			if (num == 1) {

				resource.set("丽丽", "女女女");
			} else {
				resource.set("mike", "man");
			}
			num = ++num % 2;
		}
	}
}

class Consumer implements Runnable {
	private Resource resource;

	Consumer(Resource resource) {
		this.resource = resource;
	}

	public void run() {
		while (true) {
			resource.out();
		}
	}
}

class Communicate {
	public static void main(String[] args) {
		Resource resource = new Resource();
		Producer pro = new Producer(resource);
		Consumer con = new Consumer(resource);
		Thread t1 = new Thread(pro);
		Thread t2 = new Thread(con);
		

		t1.start();
		t2.start();
		
	}
}

这个例子已经实现了生产一个就消费一个,其实这个例子就是上一篇文章中的例子,只是将代码略作优化。

但是还有一个问题,这个例子只是一个线程用来生产,一个线程用来消费,那如果多加几个线程呢?


那我们多加上几个线程试试。



class Resource {
	private String name;
	private String sex;
	private boolean flag = false;

	public synchronized void set(String name, String sex) {
		if (flag == true) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.name = name + "--" + sex;
		System.out.println(Thread.currentThread().getName() + "--生产者--"
				+ this.name);
		flag = true;
		notify();
	}

	public synchronized void out() {
		if (flag == false) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println(Thread.currentThread().getName() + "---消费者---"
				+ this.name);
		flag = false;
		notify();
	}
}

class Producer implements Runnable {
	private Resource resource;
	private int num = 0;

	Producer(Resource resource) {
		this.resource = resource;
	}

	public void run() {
		while (true) {
			if (num == 1) {

				resource.set("丽丽", "女女女");
			} else {
				resource.set("mike", "man");
			}
			num = ++num % 2;
		}
	}
}

class Consumer implements Runnable {
	private Resource resource;

	Consumer(Resource resource) {
		this.resource = resource;
	}

	public void run() {
		while (true) {
			resource.out();
		}
	}
}

class Communicate {
	public static void main(String[] args) {
		Resource resource = new Resource();
		Producer pro = new Producer(resource);
		Consumer con = new Consumer(resource);
		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();	
	}
}

在打印结果中我们发现会有这种情况:

Thread-1--生产者--mike--man

Thread-0--生产者--mike--man

Thread-2---消费者---mike--man

还可能会发生生产一个而消费两个的情况。出现的原因在 wait()这,就不过多的解释了。

只需要将判断flag 的if 改为while 同时将notify改为notifyAll() 就ok。

 

修改完如下:


class Resource {
	private String name;
	private String sex;
	private boolean flag = false;

	public synchronized void set(String name, String sex) {
		while (flag == true) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.name = name + "--" + sex;
		System.out.println(Thread.currentThread().getName() + "--生产者--"
				+ this.name);
		flag = true;
		notifyAll();
	}

	public synchronized void out() {
		while (flag == false) {
			try {
				wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println(Thread.currentThread().getName() + "---消费者---"
				+ this.name);
		flag = false;
		notifyAll();
	}
}

class Producer implements Runnable {
	private Resource resource;
	private int num = 0;

	Producer(Resource resource) {
		this.resource = resource;
	}

	public void run() {
		while (true) {
			if (num == 1) {

				resource.set("丽丽", "女女女");
			} else {
				resource.set("mike", "man");
			}
			num = ++num % 2;
		}
	}
}

class Consumer implements Runnable {
	private Resource resource;

	Consumer(Resource resource) {
		this.resource = resource;
	}

	public void run() {
		while (true) {
			resource.out();
		}
	}
}

class Communicate {
	public static void main(String[] args) {
		Resource resource = new Resource();
		Producer pro = new Producer(resource);
		Consumer con = new Consumer(resource);
		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();	
	}
}






Java---19---多线程:生产者和消费者

标签:多线程   安全   同步   thread   myeclipse   

原文地址:http://blog.csdn.net/u013476556/article/details/42875267

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!