【Java】第三十四节 线程通信

涉及到的方法:

1、wait():一旦执行次方法,当前线程就会处于阻塞状态,并自动释放同步监视器;
2、notify():唤醒执行了wait()的线程,如果有多个线程执行了wait()方法,则优先唤醒优先级高的线程,如果优先级相同,则随即唤醒一个;
3、notifyAll():唤醒所有执行了wait()的线程。

说明:

1、wait()、notify()、notifyAll()三个方法必须使用在同步代码块或同步方法中;
2、wait()、notify()、notifyAll()三个方法的调用者必须是同步监视器;
3、 wait()、notify()、notifyAll()三个方法是定义在java.lang.Object类中的,因为同步监视器可以是任意类对象。

sleep()和wait()有何区别?

1、sleep()方法声明在Thread类中,wait()声明在Object类中;
2、sleep()方法可以用在任意需要的位置,wait()只能用在同步代码块或同步方法中;
3、sleep()方法不会释放同步监视器,wait()方法会释放同步监视器。

线程通信之生产者与消费者问题:

1.需求:
生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处 取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图 生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通 知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如 果店中有产品了再通知消费者来取走产品。
2.分析:

  • 线程:生产者线程、消费者线程
  • 共享数据:店员/产品数量
  • 线程创建方式:继承Thread(随意)
  • 解决线程安全问题:同步方法(随意)

3.代码:

package cn.jingpengchong.test;

class Clerk{

	//共享数据店员实际上是共同操作产品数量
    private int productNum = 0;

	//控制产品的生产
    public synchronized void product(){

        if (productNum < 20){
            notify();
            productNum ++;
            System.out.println(Thread.currentThread().getName()+":生产产品,编号-->"+productNum);
        }else{
            //等待
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

	//控制产品的消费
    public synchronized void consum(){

        if (productNum > 0){
            notify();
            System.out.println(Thread.currentThread().getName()+":消费产品,编号-->"+productNum);
            productNum --;
        }else{
            //等待
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
}

class Productor extends Thread{

    private Clerk clerk = null;

    public Productor(Clerk clerk){
        this.clerk = clerk;

    }

    @Override
    public void run() {
        while(true) {
            clerk.product();
            //使得线程不要执行得太快,便于观察
            try {
                sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Customer extends Thread{

    private Clerk clerk = null;

    public Customer(Clerk clerk){
        this.clerk = clerk;
    }

    @Override
    public void run() {
        while(true) {
            clerk.consum();
            //使得线程不要执行得太快,便于观察
            try {
                sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class PAndCModel {

    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        Productor p = new Productor(clerk);
        Customer c = new Customer(clerk);

        p.setName("生产者");
        c.setName("消费者");

        p.start();
        c.start();
    }
}
发布了128 篇原创文章 · 获赞 17 · 访问量 2749

猜你喜欢

转载自blog.csdn.net/qq_43705275/article/details/103931475