Java多线程-线程间通信

一,等待/通知机制  实现线程间的通信

举个例子:我们去饭店就餐,饭店上餐的时间不确定,如果我们一直去询问前台,是不是很烦,我么这时就处于等待(wait)状态,但是 饭店肯定会有人肯定会通知 (notify),那个桌的菜已经做好了,前台就会通知这桌的人,菜来了。

1,主要的方法wait() /notify() 这个两个方法时Object类本地方法 都要在同步方法中调用

          1),wait() 使执行当前代码的线程进行等待,执行完毕后,线程就会释放锁,以便别的线程可以获得锁。

           2),notify(),随机挑选一个处于wait()的线程,让他获得锁,但这个方法不会立即释放当前线程的对象锁,只有程序执行完毕后,才会释放锁。

           3)sleep()方法,这个方法也是不是放锁的 ,那么别的线程要获取这个锁就会处于等待状态。

           4),在调用wait()方法后,使线程处于wait状态,这时如果调用interrupt()就会出现InterrruptedException异常

           5),notify()方法一次只会通知一个线程。notifyAll()通知所有的线程

二,使用等待/通知机制,实现生产者/消费者模式

/**
 * 通知等待机制 实现消费者者/生产者模式
 */
public class PCDemo {
    //消费品
    public static class Data{
        public static String value = " ";
    }
    //生产者
    public static class Producer{
        private String lock;
        public Producer(String value){
            this.lock = value;
        }
        public void setValue() throws Exception{
           synchronized (lock){
               if (!Data.value.equals(" ")){  //说明value没有被消费
                   lock.wait();
               }else{
                   String s = System.currentTimeMillis()+" ";
                   System.out.println("设置的value = " + s+"  当前线程的Name = "+Thread.currentThread().getName());
                   Data.value = s;//生产数据
                   lock.notify();//通知等待的消费者去消费
               }
           }
        }
    }
    //消费者
    public static class Consumer{
        private String lock;
        public Consumer(String lock){
            this.lock = lock;
        }
        public void getValue() throws Exception{
            synchronized (lock){
                if (Data.value.equals(" ")){ //说明生产者没有生产数据
                    lock.wait();//消费者等待
                }else {
                    System.out.println("消费者获得的值 "+ Data.value+"  当前线程的Name = "+Thread.currentThread().getName());
                    Data.value = " ";//模拟把数据消费了
                    lock.notify();//通知生产者赶快生产数据 ,我已经消费完了
                }
            }
        }
    }

    //生产者线程
    public static class ProThread implements Runnable{
        private Producer producer;
        public ProThread(Producer p){
            this.producer = p;
        }

        @Override
        public void run() {
            while (true){
                try {
                    producer.setValue();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //消费者线程

    public static class ConThread implements Runnable{
        private Consumer consumer;
        public ConThread(Consumer consumer){
            this.consumer = consumer;
        }
        @Override
        public void run() {
            try {
                while (true){
                    consumer.getValue();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws Exception{
        String lock = new String(" ");//使用同一个锁对象
        Thread p = new Thread(new ProThread(new Producer(lock)));
        Thread c = new Thread(new ConThread(new Consumer(lock)));
        p.setName("Producer");
        c.setName("Consumer");
        p.start();
        c.start();
    }
}

运行部分截图

这时一个生产者,一个消费者的情况,两个线程交替执行。

若果有多个消费者,多个生产者,则有可能产生“假死”现象,就是所有的线程都处于waitting,因为notify()方法一次只能使一个处于waitting状态的线程掉起来。解决办法使用notifiyAll()方法即可。

三,join():等待线程对象销毁,一个主线程要等待子线程结束在自行结束。

1,join()内部其实使用的是wait(),

 public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

join()方法具有使线程排队执行的作用,类似与同步的效果,但和synchroized的原理不同,后者使用 “对象监视器”原理

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本项目是一个基于SpringBoot开发的华府便利店信息管理系统,使用了Vue和MySQL作为前端框架和数据库。该系统主要针对计算机相关专业的正在做毕设的学生和需要项目实战练习的Java学习者,包含项目源码、数据库脚本、项目说明等,有论文参考,可以直接作为毕设使用。 后台框架采用SpringBoot,数据库使用MySQL,开发环境为JDK、IDEA、Tomcat。项目经过严格调试,确保可以运行。如果基础还行,可以在代码基础之上进行改动以实现更多功能。 该系统的功能主要包括商品管理、订单管理、用户管理等模块。在商品管理模块中,可以添加、修改、删除商品信息;在订单管理模块中,可以查看订单详情、处理订单状态;在用户管理模块中,可以注册、登录、修改个人信息等。此外,系统还提供了数据统计功能,可以对销售数据进行统计和分析。 技术实现方面,前端采用Vue框架进行开发,后端使用SpringBoot框架搭建服务端应用。数据库采用MySQL进行数据存储和管理。整个系统通过前后端分离的方式实现,提高了系统的可维护性和可扩展性。同时,系统还采用了一些流行的技术和工具,如MyBatis、JPA等进行数据访问和操作,以及Maven进行项目管理和构建。 总之,本系统是一个基于SpringBoot开发的华府便利店信息管理系统,使用了Vue和MySQL作为前端框架和数据库。系统经过严格调试,确保可以运行。如果基础还行,可以在代码基础之上进行改动以实现更多功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值