`
schy_hqh
  • 浏览: 546274 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

(多线程)多线程之间的通信

 
阅读更多

 

多线程之间通信

如生产者与消费者的通信,操作同一个共享资源

关键:通过一个标记来控制资源的状态,使用wait与notify/notifyAll实现线程的切换

生产者负责生产,满则等待,空则生产;

消费者负责消费,空则等待,有则消费;

 

单一生产者与消费者的时候,可以使用if判断标记,使用notify唤醒对方线程

 

如果在多生产者多消费者的情况下,必须使用while判断标记,使用notifyAll唤醒对方线程

因为,只有使用while循环判断,才能避免多生产的问题(生产多个,只消费1个)

只有使用notifyAll才能保证对方线程被唤醒

因为notify有可能唤醒到的是本方线程,从而导致双方线程都等待,程序无法继续运行!

 

 

生产者与消费者

 

资源

package com.gc.thread.producer;

public class Resource{

	private String name;//资源
	
	private int No;//资源编号
	
	boolean flag = false;//仓库是否有资源
	
	/**
	 * 生产者
	 * @param name
	 */
	public synchronized void produce(String name) {
		
		//如果已经生产了,则等待消费者消费
		while(flag) {
			try {
				this.wait();//每次被唤醒都重新判断标记
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		//为商品编号
		this.name = name + (++No);

		//生产1个商品
		System.out.println(Thread.currentThread().getName()+"--->生产:" + this.name);
		
		//更新标记
		this.flag = true;
		
		//唤醒消费者(如果使用notify唤醒1个线程,不能保证一定唤醒到的是对方线程,如果唤醒到了本方线程,则可能造成双方线程都处于冻结状态,程序将无法继续运行)
		this.notifyAll();
	}
	
	/**
	 * 消费者
	 */
	public synchronized void consume() {
		//如果没有商品,则等待生产者生产
		while(!flag) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
		//消费1个商品
		System.out.println(Thread.currentThread().getName()+"------>消费:" + this.name);
		
		//更新标记
		this.flag = false;
		
		//唤醒生产者
		this.notifyAll();
	}
	
}

 生产者

package com.gc.thread.producer;

public class Producer implements Runnable {

	private Resource r;
	
	public Producer(Resource r) {
		this.r = r;
	}
	
	@Override
	public void run() {
		while(true)
			r.produce("goods");
	}

}

 消费者

package com.gc.thread.producer;

public class Consumer implements Runnable {

	private Resource r;
	
	public Consumer(Resource r) {
		this.r = r;
	}
	
	@Override
	public void run() {
		while(true)
			r.consume();
	}

}

 开启线程

package com.gc.thread.producer;

public class Demo {
	public static void main(String[] args) {
		
		//资源
		Resource r = new Resource();
		
		//生产者
		Producer producer1 = new Producer(r);
		Producer producer2 = new Producer(r);
		
		//消费者
		Consumer consumer1 = new Consumer(r);
		Consumer consumer2 = new Consumer(r);
		
		new Thread(producer1).start();
		new Thread(producer2).start();
		new Thread(consumer1).start();
		new Thread(consumer2).start();
	}
}

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics