多线程并发操作之经典案例(生产者和消费者)

生产者和消费者问题


实际案例:

两个在写多线程程序时容易犯的错误

  • 当多个线程共同去操作同一份数据时,注意使用线程的同步保证信息的同步性和安全性。
  • 遇到生产者和消费者这类问题,如果希望生产者生产之后立刻有消费者拿走,不出现重复生产与重复消费的现象,就需要使用Object的两个方法(唤醒和等待).当生产者生产玩一个信息后立刻有消费者读取此信息,需要有一个标志位。
package june_2th;
/** * 测试类 * @Hudie */
public class Test {
	public static void main(String[] args) {
		Movie movie = new Movie();
		Thread producer = new Thread(new Producer(movie));
		Thread consumer = new Thread(new Consumer(movie));
		producer.start();
		consumer.start();
	}
}
package june_2th;
/** * 电影类 * * @Hudie */
public class Movie {
	private String name;
	private String info;
	private boolean flag = true;// 设置标志位,控制生产者生成,消费者消费

	public String getName() {
		return name;
	}

	public String getInfo() {
		return info;
	}

	// 该同步方法,可以为两个方法赋值
	public synchronized void set(String name, String info) {
		if (!flag) {
			try {
				super.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.name = name;
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		this.info = info;
		flag = false;// 重置标志位,让消费者消费
		super.notify();// 唤醒消费者进程
	}

	public synchronized void get() {
		if (flag) {
			try {
				super.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println(this.getName() + "-" + this.getInfo());
		flag = true;
		super.notify();
	}
}
package june_2th;
/** * 生产者 * @Hudie */
public class Producer implements Runnable {
	private Movie movie = null;
	private boolean flag = false;

	public Producer(Movie movie) {
		super();
		this.movie = movie;
	}

	@Override
	public void run() {
		// 循环录入五十遍电影数据,两部电影交替录入
		for (int i = 0; i < 50; i++) {
			if (flag) {
				this.movie.set("变形金刚", "一部科幻电影");
				flag = false;
			} else {
				this.movie.set("神偷奶爸", "一部3D动画电影");
				flag = true;
			}
		}
	}
}
package june_2th;
/** * 消费者 * @Hudie */
public class Consumer implements Runnable {
	private Movie movie = null;

	public Consumer(Movie movie) {
		super();
		this.movie = movie;
	}

	@Override
	public void run() {
		// 循环显示五十次电影信息
		for (int i = 0; i < 50; i++) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			this.movie.get();
		}
	}
}

测试结果:

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务