生产者与消费者问题主要解决的是同步问题:
可知三者关系,生产者与消费者共同作用于目标对象,但生产者与消费者之间又存在先后关系。
生产者——>生成一定量的数据放到缓冲区中,然后重复此过程;
消费者——>在缓冲区消耗这些数据。
而生产者-消费者之间存在三种关系,即
生产者与生产者之间是互斥关系;
消费者与消费者之间是互斥关系;
生产者与消费者之间是同步与互斥关系。
下面直接用代码讲解:
//目标对象类
package 生产者与消费者一对一队列操作;
import java.util.ArrayList;
import java.util.List;
public class CookieList {
public static final int MAX_SIZE = 1;
private List list = new ArrayList();
public synchronized void product(){
try{
if(list.size()==MAX_SIZE)
this.wait();
list.add("cookie"+((int)(Math.random()*10)+1));
System.out.println("生产者生产了"+list.get(0));
this.notify();
}catch(InterruptedException e){
}
}
public synchronized void customer(){
try{
if(list.size()==0)
this.wait();
System.out.println("消费者消费了:"+list.get(0));
list.remove(0);
this.notify();
}catch(InterruptedException e){
}
}
}
Main类
package 生产者与消费者一对一队列操作;
public class Main {
public static void main(String[] args) {
CookieList cookieList = new CookieList();
P p = new P(cookieList);
C c = new C(cookieList);
p.start();
c.start();
}
//生产者线程
public static class P extends Thread{
public CookieList cookieList;
public P(CookieList cookieList){
this.cookieList = cookieList;
}
@Override
public void run() {
while(true){
this.cookieList.product();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
//消费者线程
public static class C extends Thread{
public CookieList cookieList;
public C(CookieList cookieList){
this.cookieList = cookieList;
}
@Override
public void run() {
while(true){
this.cookieList.customer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
}
比如针对消费者,当需要唤醒生产者生产时可以调用notify()方法,但notify()方法并不能指定唤醒监视队列特定的线程而是随机唤醒的,当多个消费者的时候一个消费者唤醒的可能是另一个消费者线程而不是生产者线程,所以当有多个消费者或多生产者的情况下可以使用notifyAll()以防止程序出现“假死现象”(即线程全都处于阻塞状态),及需注意while(){wait()}的使用
具体请看以下代码
package 生产者与消费者一生产多消费队列操作;
import java.util.ArrayList;
import java.util.List;
public class CookieList {
public static final int MAX_SIZE = 1;
private List list = new ArrayList();
public synchronized void product(){
try{
if(list.size()==MAX_SIZE)
this.wait();
list.add("cookie"+((int)(Math.random()*10)+1));
System.out.println("生产者生产了"+list.get(0));
this.notify();
}catch(InterruptedException e){
}
}
public synchronized void customer(){
try{
//注意while
while(list.size()==0)
this.wait();
System.out.println("消费者消费了:"+list.get(0));
list.remove(0);
this.notifyAll();
}catch(InterruptedException e){
}
}
}
Main
package 生产者与消费者一生产多消费队列操作;
public class Main {
public static void main(String[] args) {
CookieList cookieList = new CookieList();
P p = new P(cookieList);
C c = new C(cookieList);
p.start();
c.start();
for(int i=0;i<3;++i){
c = new C(cookieList);
c.start();
}
}
//生产者线程
public static class P extends Thread{
public CookieList cookieList;
public P(CookieList cookieList){
this.cookieList = cookieList;
}
@Override
public void run() {
while(true){
this.cookieList.product();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
//消费者线程
public static class C extends Thread{
public CookieList cookieList;
public C(CookieList cookieList){
this.cookieList = cookieList;
}
@Override
public void run() {
while(true){
this.cookieList.customer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
}
package 生产者与消费者一消费多生产队列操作;
import java.util.ArrayList;
import java.util.List;
public class CookieList {
public static final int MAX_SIZE = 1;
private List list = new ArrayList();
public synchronized void product(){
try{
while(list.size()==MAX_SIZE)
this.wait();
list.add("cookie"+((int)(Math.random()*10)+1));
System.out.println("生产者生产了"+list.get(0));
this.notifyAll();
}catch(InterruptedException e){
}
}
public synchronized void customer(){
try{
//注意while
if(list.size()==0)
this.wait();
System.out.println("消费者消费了:"+list.get(0));
list.remove(0);
this.notify();
}catch(InterruptedException e){
}
}
}
Main
package 生产者与消费者一消费多生产队列操作;
public class Main {
public static void main(String[] args) {
CookieList cookieList = new CookieList();
P p = new P(cookieList);
C c = new C(cookieList);
p.start();
c.start();
for(int i=0;i<3;++i){
p = new P(cookieList);
p.start();
}
}
//生产者线程
public static class P extends Thread{
public CookieList cookieList;
public P(CookieList cookieList){
this.cookieList = cookieList;
}
@Override
public void run() {
while(true){
this.cookieList.product();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
//消费者线程
public static class C extends Thread{
public CookieList cookieList;
public C(CookieList cookieList){
this.cookieList = cookieList;
}
@Override
public void run() {
while(true){
this.cookieList.customer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
}
package 多生产多消费队列操作;
import java.util.ArrayList;
import java.util.List;
public class CookieList {
public static final int MAX_SIZE = 5;
private List list = new ArrayList();
public synchronized void product(){
try{
while(list.size()==MAX_SIZE)
this.wait();
list.add("cookie"+((int)(Math.random()*10)+1));
System.out.println("生产者生产了"+list.get(0));
this.notifyAll();
}catch(InterruptedException e){
}
}
public synchronized void customer(){
try{
//注意while
while(list.size()==0)
this.wait();
System.out.println("消费者消费了:"+list.get(0));
list.remove(0);
this.notifyAll();
}catch(InterruptedException e){
}
}
}
Main
package 多生产多消费队列操作;
public class Main {
public static void main(String[] args) {
CookieList cookieList = new CookieList();
P p = new P(cookieList);
C c = new C(cookieList);
p.start();
c.start();
for(int i=0;i<3;++i){
c = new C(cookieList);
c.start();
p = new P(cookieList);
p.start();
}
}
//生产者线程
public static class P extends Thread{
public CookieList cookieList;
public P(CookieList cookieList){
this.cookieList = cookieList;
}
@Override
public void run() {
while(true){
this.cookieList.product();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
//消费者线程
public static class C extends Thread{
public CookieList cookieList;
public C(CookieList cookieList){
this.cookieList = cookieList;
}
@Override
public void run() {
while(true){
this.cookieList.customer();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
}
}