Java并发编程-07-在同步代码中使用条件--生产者-消费者问题

一、在同步代码中使用条件

wait()

notify()

notifyAll()


二、 wait()

1、只能在同步代码块中调用

2、当一个线程调用wait()方法事,jvm将这个线程置入休眠,并且释放控制这个同步代码快的对象,同时允许其他线程执行这个对象控制的其他同步代码快

3、为了唤醒这个线程,必须在这个对象控制的某个同步代码快调用notify()方法或者notifyAll()方法


三、实现生产者-消费者问题

package com.concurrent.threadSynchronize;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * 存储类
 * 
 * @author Nicholas
 *
 */
public class EventStorage {

	private int maxSize;
	private List<Date> storage;

	public EventStorage() {
		maxSize = 10;
		storage = new LinkedList<Date>();
	}

	/**
	 * 同步方法,set,保存数据到storage中 
	 * 1、首先,检查列表是不是满的,如果是满的,那么调用wait()方法等待空闲空间出现
	 * 2、最后,调用notifyAll()方法,唤醒所有因调用wait()方法而休眠的线程
	 */
	public synchronized void set() {
		while (storage.size() == maxSize) {
			try {
				System.out.println("Please Wait,the storage is full...");
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		storage.add(new Date());
		System.out.println("Set : " + storage.size());

		// 唤醒
		notifyAll();
	}

	/**
	 * 同步方法get,从storage中获取数据 
	 * 1、检查列表是否有数据,如果没有,那么调用wait()方法等待 
	 * 2、最后调用notifyAll()唤醒
	 */

	public synchronized void get() {
		while (storage.size() == 0) {
			try {
				System.out.println("Please Wait,the storage is empty...");
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("Get : size = " + storage.size() + " Value = "
				+ ((LinkedList<?>) storage).poll());
		notifyAll();
	}
}

package com.concurrent.threadSynchronize;

/**
 * 生产者类
 * 
 * @author Nicholas
 *
 */
public class Producer implements Runnable {

	private EventStorage eventStorage;

	public Producer(EventStorage eventStorage) {
		this.eventStorage = eventStorage;
	}

	@Override
	public void run() {
		for(int i = 0;i<100;i++) {
			eventStorage.set();
		}
	}
}

package com.concurrent.threadSynchronize;

/**
 * 消费者类
 * 
 * @author Nicholas
 *
 */
public class Consumer implements Runnable {

	private EventStorage eventStorage;

	public Consumer(EventStorage eventStorage) {
		this.eventStorage = eventStorage;
	}

	@Override
	public void run() {
		for (int i = 0; i < 100; i++) {
			eventStorage.get();
		}
	}
}

package com.concurrent.threadSynchronize;

public class Main {

	public static void main(String[] args) {
		EventStorage eventStorage = new EventStorage();

		Producer producer = new Producer(eventStorage);
		Consumer consumer = new Consumer(eventStorage);

		Thread producerThread = new Thread(producer);
		Thread consumerThread = new Thread(consumer);

		producerThread.start();
		
		consumerThread.start();
	}

}

结果:

Set : 1
Set : 2
Set : 3
Set : 4
Set : 5
Set : 6
Set : 7
Set : 8
Set : 9
Set : 10
Please Wait,the storage is full...
Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015
Please Wait,the storage is empty...
Set : 1
Set : 2
Set : 3
Set : 4
Set : 5
Set : 6
Set : 7
Set : 8
Set : 9
Set : 10
Please Wait,the storage is full...
Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015
Please Wait,the storage is empty...
Set : 1
Set : 2
Set : 3
Set : 4
Set : 5
Set : 6
Set : 7
Set : 8
Set : 9
Set : 10
Please Wait,the storage is full...
Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Set : 8
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015
Please Wait,the storage is empty...
Set : 1
Set : 2
Set : 3
Set : 4
Set : 5
Set : 6
Set : 7
Set : 8
Set : 9
Set : 10
Please Wait,the storage is full...
Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015
Please Wait,the storage is empty...
Set : 1
Set : 2
Set : 3
Set : 4
Set : 5
Set : 6
Set : 7
Set : 8
Set : 9
Set : 10
Please Wait,the storage is full...
Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015
Please Wait,the storage is empty...
Set : 1
Set : 2
Set : 3
Set : 4
Set : 5
Set : 6
Set : 7
Set : 8
Set : 9
Set : 10
Please Wait,the storage is full...
Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015
Please Wait,the storage is empty...
Set : 1
Set : 2
Set : 3
Set : 4
Set : 5
Set : 6
Set : 7
Set : 8
Set : 9
Set : 10
Please Wait,the storage is full...
Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015
Please Wait,the storage is empty...
Set : 1
Set : 2
Set : 3
Set : 4
Set : 5
Set : 6
Set : 7
Set : 8
Set : 9
Set : 10
Please Wait,the storage is full...
Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015
Please Wait,the storage is empty...
Set : 1
Set : 2
Set : 3
Set : 4
Set : 5
Set : 6
Set : 7
Set : 8
Set : 9
Set : 10
Please Wait,the storage is full...
Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015
Please Wait,the storage is empty...
Set : 1
Set : 2
Set : 3
Set : 4
Set : 5
Set : 6
Set : 7
Set : 8
Set : 9
Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015
Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015


四、wait()和sleep()的区别


1、sleep()是Thread类的静态方法

public static native void sleep(long millis) throws InterruptedException;

谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep

2、wait是object类的方法

public final void wait() throws InterruptedException {
<span style="white-space:pre">	</span>wait(0);
}

最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法

3、sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。

一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,必须要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。

sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。

Thread.sleep(0)的作用是触发操作系统立刻重新进行一次CPU竞争。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值