• 在Java线程中,wait、notify、notifyAll的用法


    wait方法:当前线程转入阻塞状态,让出cpu的控制权,解除锁定。

      notify方法:唤醒因为wait()进入阻塞状态的其中一个线程。

      notifyAll方法: 唤醒因为wait()进入阻塞状态的所有线程。

         synchronized(线程同步)可以修饰方法,或者方法内部的代码块。被synchronized修饰的代码块表示:一个线程在操作该资源时,不允许其他线程操作该资源。

      这三个方法都必须用synchronized块来包装,而且必须是同一把锁,不然会抛出java.lang.IllegalMonitorStateException异常。

     

    下面是一个生产者、消费者例子:

    复制代码
    public class ProductConsumer {
        public static int i = 0;
    
        public static void main(String[] args) {
            ProductStack ps = new ProductStack();
            Product product = new Product(ps);
            new Thread(product).start();
    
            Consumer consumer = new Consumer(ps);
            new Thread(consumer).start();
        }
    
    }
    
    class Product implements Runnable {
        ProductStack ps = null; 
        Product(ProductStack ps) {
            this.ps = ps;
        }
        @Override
        public void run() {
            while (true) {
                if (ProductConsumer.i < 100) {
                    ps.push();
                }else{
                    break;
                }
            }
        }
    
    }
    
    class Consumer implements Runnable {
        ProductStack ps = null;
            Consumer(ProductStack ps) {
                this.ps = ps;
            }
    
        @Override
        public void run() {
            while (true) {
                if (ProductConsumer.i < 100) {
                    ps.pop();
                }else{
                    break;
                }
            }
        }
    
    }
    
    class ProductStack {
        boolean isPro = true;
        public synchronized void push() {
            if (!isPro) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            notifyAll();
            ProductConsumer.i++;
            System.out.print("第" + ProductConsumer.i + "个产品,生产者:"
                    + Thread.currentThread().getName());
            isPro = false;
            try {
                Thread.sleep((int) Math.random() * 200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
        }
    
        public synchronized void pop() {
            if (isPro) {
                try {
                    wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            notifyAll();
            System.out.println(",消费者:" + Thread.currentThread().getName());
            isPro = true;
            try {
                Thread.sleep((int) Math.random() * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
  • 相关阅读:
    gitlab环境搭建
    PHP能引起安全的函数
    PHP扩展安装方法
    如果Centos没有桌面,怎么修改IP地址
    解决docker 下来镜像出现 error pulling image configuration: Get https://dseasb33srnrn.cloudfront.net的问题
    systemd详解(CentOS 7)
    正确修改MySQL最大连接数的三种好用方案
    CentOS7 yum安装mysql5.5/5.6并初始化
    CentOS7系统配置国内yum源和epel源
    导入镜像后,容器内httpd起不来
  • 原文地址:https://www.cnblogs.com/a892647300/p/2646592.html
Copyright © 2020-2023  润新知