生产者和消费者之间的阻塞队列
生产者消费者模型在实际生活中很多运用。对我们自己来说就是一个消费者,比如我们需要买奥利奥饼干,我们会去超时买,并不是直接从厂商那里买,而厂商把奥利奥生产结束后会送往各个超市进行售卖,超市就是我们消费者和生产者之间媒介。这个超市在操作系统定义为阻塞队列。
生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从
阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
在了解生产者消费者模型之前需要先了解几个方法~~
wait()方法
public final void wait() throws InterruptedException
wait()使线程停止运行,会释放对象锁。
- wait()方法必须用于同步代码块和同步方法,而且必须是内建锁(synchronized),因为需要锁住的对象。如果调用wait()时没有合适的锁,会抛异常。
- wait()方法会使当前线程调用该方法后进行等待,并且将该线程置入锁对象的等待队列中,直到接到通知或被中断而已。如果没有接到通知或者中断,会一直等。
- wait()方法执行后当前线程释放锁,其他线程可以竞争该锁。
package CODE.多线程;
public class Wait1
{
public static void main(String[] args) throws InterruptedException {
Object ob=new Object();
synchronized (ob)
{
System.out.println("等待开始...");
ob.wait();
System.out.println("等待结束...");
}
System.out.println("main方法结束...");
}
}
只会打印出“等待开始…”,因为没有唤醒等待,该进程就一直等待…,不会运行后面语句。
wait方法从运行态到阻塞态
wait (long time):如果到了预计时间还没被唤醒,将继续执行后续代码
wait( )之后的线程继续执行有2种方法:
- 调用该对象的notify( )方法唤醒等待线程
- 线程等待时调用interrupt( )中断该线程
1.首先用notify()唤醒线程:
notify()
public final native void notify();
- notify( )方法也必须在同步方法或者同步代码块中调用,用来唤醒等待在该对象上的线程。如果有多个线程等待,则任意挑一个线程唤醒.
- notify( )方法执行后,唤醒线程不会立即释放对象锁,要等待唤醒线程全部执行才会释放锁。
import static java.lang.Thread.sleep;
//notify()
class waitnotifyT
{
synchronized public void waitMethod() {
System.out.println("等待开始...");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("等待结束...");
}
synchronized public void notifyMethod() {
System.out.println("唤醒开始...");
notify();
System.out.println("唤醒结束...");
}
}
class Mthread implements Runnable
{
private waitnotifyT waitnotifyT1;
private int flag=1;
public Mthread(waitnotifyT waitnotifyT1,int flag) {
this.waitnotifyT1 = waitnotifyT1;
this.flag=flag;
}
@Override
public void run()
{
if(flag==1)
{
waitnotifyT1.waitMethod();
}
else
waitnotifyT1.notifyMethod();
}
}
public class Wait1
{
public static void main(String[] args) throws InterruptedException {
waitnotifyT wn=new waitnotifyT();
Mthread waitThread=new Mthread(wn,1);
Mthread notifyThread=new Mthread(wn,0);
new Thread(waitThread