您的位置:首页 > 编程语言 > Java开发

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

2015-06-14 21:12 423 查看
一、在同步代码中使用条件

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竞争。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: