zoukankan      html  css  js  c++  java
  • Java——线程间通信

    线程间通信
    █ 针对同一个资源的操作有不同的线程
          ☞ 举例:买点影票有卖出的,也有退票的
    █ Demo
          ☞ 通过生产线程 和消费线程,对一个生产对象进行操作。

    等待唤醒机制
    █ Object
    >Wait()       // 执行wait会自动释放锁     
    >Notify()    //会唤醒其他等待进程,但是不会释放锁;通知其他进程可以执行,其他进程获得可以执行的一个条件进入同步阻塞,当进程获得锁的时候就进入就绪状态    
    >notifyAll()
    为什么不定义在Thread类中?
    //因为锁可以是任意对象。若以线程间通信机制的api必须所有对象都有

    线程状态转换图



    Baozi.java TestMain.java
    package com.java.thread_PV;

    public class Baozi {
            private String name;
            private String price;
            private boolean flag;    //flag 为false的时候表示没有数据,为true表示有数据;不初始化默认为FALSE
            public String getName() {
                    return name;
            }
            public void setName(String name) {
                    this.name = name;
            }
            public String getPrice() {
                    return price;
            }
            public void setPrice(String price) {
                    this.price = price;
            }
            public Baozi(String name, String price) {
                    super();
                    this.name = name;
                    this.price = price;
            }
            public boolean isFlag() {
                    return flag;
            }
            public void setFlag(boolean flag) {
                    this.flag = flag;
            }
    }

    package com.java.thread_PV;
    public class TestMain {

            public static void main(String[] args) {
                    Baozi baozi=new Baozi(null,null);    //同一个对象,后面确保同一把锁
                    Producer producer=new Producer(baozi);
                    Customer customer=new Customer(baozi);

                    producer.start();
                    customer.start();
            }

    }
    Producer.java Customer.java
    package com.java.thread_PV;
    public class Producer extends Thread {
            Baozi baozi;
            public Producer(Baozi baozi2) {
                    baozi = baozi2;
            }

            public void run() {
                    super.run();
                    int i = 0;
                    while (true) {
                            synchronized (baozi) {  //notify 和  wait 机制需要放到同步代码快里使用
                                    if (baozi.isFlag()) {  // flag 为true表示有包子
                                            // 等待 (放弃执行权,让其他线程执行。消费者去消费)
                                            try {
                                                    baozi.wait();
                                            } catch (InterruptedException e) {
                                                    e.printStackTrace();
                                            }
                                    }
                                    // 没有包子就生产
                                    if (i % 2 == 0) {
                                            baozi.setName("天津狗不理");
                                            baozi.setPrice("10RMB");
                                    } else {
                                            baozi.setName("无锡灌汤包");
                                            baozi.setPrice("5RMB");
                                    }
                                    i++;
                                    // 生产完之后?改变标记flag为true,通知消费者来消费
                                    baozi.setFlag(true);
                                    baozi.notify();   // 通知消费者,但是消费者并不能立即执行;要等后面的代码全部执行完释放锁后,消费者进程抢到锁才能执行
                            }
                    }
            }
    }
    package com.java.thread_PV;
    public class Customer extends Thread {
            Baozi baozi;
            public Customer(Baozi baozi2) {
                    baozi = baozi2;
            }

            public void run() {
                    super.run();
                    while (true) {
                            synchronized (baozi) {
                                    if (!baozi.isFlag()) { // false 表示没有包子,就等待
                                            try {
                                                    baozi.wait();  //等待的时候放弃cpu执行权。。但是这里要释放锁!!这里wait方法会自动释放锁,所以不会形成死锁
                                            } catch (InterruptedException e) {
                                                    e.printStackTrace();
                                            }
                                    }
                                    // 如果有就消费
                                    System.out.println("Customer.consume()" + baozi.getName() + " :" + baozi.getPrice());
                                    // 消费完就修改标记,通知生产者去生产
                                    baozi.setFlag(false);
                                    baozi.notify();  // 通知生产者,notify不会释放锁,如果下面还有代码,这里还会接着执行,不会释放锁;另外的进程不会拿到锁,会进入同步阻塞;拿到锁就进入就绪状态
                            }

                    }

            }
    }




















  • 相关阅读:
    安装mysql
    date, Calendar
    心态
    jdbc ---- DBUTilDao 类
    jdbc--------JdbcUtilDao 类
    Python与C/C++相互调用
    用链表和数组实现HASH表,几种碰撞冲突解决方法
    用链表实现消息队列
    文件系统的发展
    [深度学习]开源的深度学习框架
  • 原文地址:https://www.cnblogs.com/meihao1203/p/9181814.html
Copyright © 2011-2022 走看看