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

来源:互联网 发布:中国柬埔寨关系 知乎 编辑:程序博客网 时间:2024/05/18 12:04

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

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;}@Overridepublic 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;}@Overridepublic 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 : 1Set : 2Set : 3Set : 4Set : 5Set : 6Set : 7Set : 8Set : 9Set : 10Please Wait,the storage is full...Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015Please Wait,the storage is empty...Set : 1Set : 2Set : 3Set : 4Set : 5Set : 6Set : 7Set : 8Set : 9Set : 10Please Wait,the storage is full...Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015Please Wait,the storage is empty...Set : 1Set : 2Set : 3Set : 4Set : 5Set : 6Set : 7Set : 8Set : 9Set : 10Please Wait,the storage is full...Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Set : 8Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015Please Wait,the storage is empty...Set : 1Set : 2Set : 3Set : 4Set : 5Set : 6Set : 7Set : 8Set : 9Set : 10Please Wait,the storage is full...Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015Please Wait,the storage is empty...Set : 1Set : 2Set : 3Set : 4Set : 5Set : 6Set : 7Set : 8Set : 9Set : 10Please Wait,the storage is full...Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015Please Wait,the storage is empty...Set : 1Set : 2Set : 3Set : 4Set : 5Set : 6Set : 7Set : 8Set : 9Set : 10Please Wait,the storage is full...Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015Please Wait,the storage is empty...Set : 1Set : 2Set : 3Set : 4Set : 5Set : 6Set : 7Set : 8Set : 9Set : 10Please Wait,the storage is full...Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015Please Wait,the storage is empty...Set : 1Set : 2Set : 3Set : 4Set : 5Set : 6Set : 7Set : 8Set : 9Set : 10Please Wait,the storage is full...Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015Please Wait,the storage is empty...Set : 1Set : 2Set : 3Set : 4Set : 5Set : 6Set : 7Set : 8Set : 9Set : 10Please Wait,the storage is full...Get : size = 10 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 1 Value = Sun Jun 14 21:14:44 CST 2015Please Wait,the storage is empty...Set : 1Set : 2Set : 3Set : 4Set : 5Set : 6Set : 7Set : 8Set : 9Get : size = 9 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 8 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 7 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 6 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 5 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 4 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 3 Value = Sun Jun 14 21:14:44 CST 2015Get : size = 2 Value = Sun Jun 14 21:14:44 CST 2015Get : 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竞争。
0 0