JavaSE the production of consumer models

wait () method

1. 方法wait()的作用是使当前执行代码的线程进行等待,wait()方法是Object类的方法,该方法是用来将当前线程置
入“预执行队列”中,并且在wait()所在的代码处停止执行,直到接到通知或被中断为止。
2. wait()方法只能在同步方法中或同步块中调用。如果调用wait()时,没有持有适当的锁,会抛出异常
3. wait()方法执行后,当前线程释放锁,其它线程可以竞争锁。
范例:wait()的使用方法
class MyThread implements Runnable{
    private Object obj=new Object();

    public void run(){
        synchronized (obj){
            System.out.println("wait start.....");
            try {
            //如果不中断线程,线程就会一直死等
                obj.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("wait end....");
        }
    }
}
class Test {
    public static void main(String[] args) throws InterruptedException {
      MyThread myThread=new MyThread();
      Thread thread=new Thread(myThread,"A");
      thread.start();
      Thread.sleep(3000);//休眠三秒钟
      //在线程等待时中断该线程
      thread.interrupt();
    }
}
范例:wait(long timeout)的使用方法
class MyThread implements Runnable{
    private Object obj=new Object();
    public void run(){
        synchronized (obj){
            System.out.println("wait start.....");
            try {
            //如果一秒钟之内线程还没有被唤醒,一秒后线程继续执行
                obj.wait(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("wait end....");
        }
    }
}
class Test {
    public static void main(String[] args) throws InterruptedException {
      MyThread myThread=new MyThread();
      Thread thread=new Thread(myThread,"A");
      thread.start();
    }
}

notify () method

notify method is to stop the thread continues to run.

  1. The method notify () method should be in sync or sync block called, which is used to notify other threads that may be waiting for this object's lock, its notification notify, and make them re-acquire the object lock of the object. If there are multiple threads waiting, then there is a thread planner randomly selected out of a thread in a wait state.
  2. After the notify () method, the current thread will not immediately release the object lock, until the thread execution notify () method of executing the program, which is then synchronized block exit will release the object lock.

Examples: notify () wake a random thread

class MyThread implements Runnable{
    private Object obj;
    private boolean flag;

    public MyThread(Object obj, boolean flag) {
        this.obj = obj;
        this.flag = flag;
    }

    public void waitMethod() {
        synchronized (obj) {
            System.out.println("wait start..."+Thread.currentThread().getName());

            try {
                obj.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("wait end...."+Thread.currentThread().getName());
        }
    }

    public void notifyMethod() {
        synchronized (obj) {
            System.out.println("notify start..." + Thread.currentThread().getName());
            obj.notify();
            System.out.println("notify end...." + Thread.currentThread().getName());
        }
    }

    @Override
    public void run() {
        if(flag){
            waitMethod();
        }else{
            notifyMethod();
        }
    }
}
class Test {
    public static void main(String[] args) throws InterruptedException {
        Object obj=new Object();
      MyThread myThread=new MyThread(obj,true);
      MyThread myThread1=new MyThread(obj,false);
      for(int i=0;i<5;i++) {
          Thread thread1 = new Thread(myThread, "等待线程"+i);
          thread1.start();
      }
      Thread thread2=new Thread(myThread1,"唤醒线程");
      Thread.sleep(1000);
      thread2.start();
    }
}

The result: only a random thread wakes up another thread to die, etc.
Here Insert Picture Description

If you want to wake up all the threads of the dead, etc., you can use notifyAll (), usage and notify () the same.
Note: wait, notify synchronized synchronization method must be used or the code block

Thread blocks

1. 线程调用 sleep()方法,主动放弃占用的处理器资源,但是不会释放对象锁。
2. 线程调用了阻塞式IO方法(read(),write()),在该方法返回前,线程被阻塞。
3. 线程试图获得一个同步监视器,但该同步监视器正被其他线程所持有。
4. 线程等待某个通知,即调用wait(),释放对象锁。
5.  程序调用了 suspend方法将该线程挂起。此方法容易导致死锁,尽量避免使用该方法。

run () method after the end of the run into the period of destruction, the entire thread is finished.

monitor two queues

Each lock object has two queues, one is ready queue, a queue is blocked. Ready queue to be stored in the thread to acquire a lock, blocking queue stores blocked thread. After a thread wakes up, it will enter the ready queue, waiting for the CPU scheduling; on the contrary, after a thread is wait, will enter the blocking queue, waiting to be awakened once.

Producer and consumer model

Example: producers and consumers to achieve more process model

package hhh.pre.java;

import java.util.ArrayList;
import java.util.List;

//商品类
class Goods{
    private String goodName;//商品名字
    private int count;//商品数量

    //生产了一个商品
    public synchronized void set(String goodName){
        while(count>0){
            System.out.println("商品还有很多,可以打个盹休息一下~~~");
            try {
                //等待消费者消费
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.goodName=goodName;
        this.count++;
        System.out.println(toString()+Thread.currentThread().getName());
        //唤醒等待消费的线程
        notifyAll();
    }

    public synchronized void get(){
        while(this.count==0){
            System.out.println("商品买完啦,稍等一下,我们正在拼命生产~~~");
            try {
                //等待生产者生产
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.count--;
        System.out.println(toString()+Thread.currentThread().getName());
        //唤醒生产者继续生产商品
        notifyAll();
    }

    @Override
    public String toString() {
        return "Goods{" +
                "goodName='" + goodName + '\'' +
                ", count=" + count +
                '}';
    }
}

//消费者线程
class Consumer implements Runnable{
   private Goods goods=new Goods();

    public Consumer(Goods goods) {
        this.goods = goods;
    }

    @Override
    public void run() {
        while(true) {
            goods.get();
        }
    }
}

//
class Producer implements Runnable{
    private Goods goods=new Goods();

    public Producer(Goods goods) {
        this.goods = goods;
    }

    @Override
    public void run() {
        while(true) {
            goods.set("MAC");
        }
    }
}
class Test {
    public static void main(String[] args) throws InterruptedException {
     Goods goods=new Goods();

     //存储多个生产、消费者线程
     List<Thread> list =new ArrayList<>();

     for(int i=0;i<10;i++){
         Thread thread=new Thread(new Consumer(goods),"消费者"+i);
         list.add(thread);
     }
     for(int i=0;i<5;i++){
         Thread thread=new Thread(new Producer(goods),"生产者"+i);
         list.add(thread);
     }
     for(Thread thread:list){
         thread.start();
     }
    }
}

operation result:
Here Insert Picture Description

Published 87 original articles · won praise 73 · views 10000 +

Guess you like

Origin blog.csdn.net/HL_HLHL/article/details/84635369