• Java第二十五天,多线程之等待唤醒机制


    当线程被创建并且被启动之后,它既不是一启动就进入了执行状态,也不是一直处于执行状态,而是具有以下多种状态:

    这六种状态之间的转换关系如下:

    1.等待唤醒机制

    注意:

    (1)两个线程之间必须用同步代码块给包裹起来,保证等待和唤醒线程同一时间段只能有一个执行,用以保证共享数据安全。

    (2)同步使用的锁对象必须是同一个对象。

    (3)必须使用锁对象的wait()和notify()方法完成等待唤醒的操作。

    (4)要注意多个被synchronized修饰的代码块是只允许在同一时刻运行一个;也就是说如果要和循环(特别是死循环)配合使用的话,要注意二者之间的包含关系。

    代码:

    package com.lanyue.day25;
    
    public class Consumer extends Thread{
    
        Resource r = null;
    
        public void setLock(Resource r){
    
            this.r = r;
        }
    
        @Override
        public void run() {
    
            while(true){
    
                synchronized (r){
    
                    try {
                        r.wait();
                    } catch (InterruptedException e) {
                        System.out.println("系统发生奔溃");
                    }
    
                    try {
    
                        System.out.println("消费中======>");
                        Thread.sleep(1000);
                        r.num--;
                        r.isEmpty = true;
                        System.out.println("当前货物剩余量:" + r.num);
                        Thread.sleep(1000);
    
                    } catch (InterruptedException e) {
    
                        System.out.println("系统奔溃");
                    }
    
                }
            }
        }
    }
    package com.lanyue.day25;
    
    public class Producer extends Thread{
    
        Resource r = null;
    
        public void setLock(Resource r){
    
            this.r = r;
        }
    
        @Override
        public void run() {
    
            while(true){
    
                synchronized (r){
    
                    if(r.isEmpty){
    
                        try {
    
                            System.out.println("生产中======>");
                            Thread.sleep(1000);
                            r.num++;
                            r.isEmpty = false;
                            System.out.println("当前货物剩余量:" + r.num);
                            Thread.sleep(1000);
    
                        } catch (InterruptedException e) {
    
                            System.out.println("系统奔溃");
                        }
    
    
                    }else{
    
                        r.notify();
                    }
                }
            }
        }
    }
    package com.lanyue.day25;
    
    public class Resource {
    
        public boolean isEmpty = true;
        public Integer num = 0;
    }
    package com.lanyue.day25;
    
    public class TestDemo {
    
        public static void main(String[] args) {
    
            Resource r = new Resource();
    
            Producer in = new Producer();
            Consumer out = new Consumer();
    
            in.setLock(r);
            out.setLock(r);
    
            in.start();
            out.start();
        }
    }
    

    很多人会纳闷为什么是

    while(true){

          synchronized(obj){

          }

    }

    而不是

    synchronized(obj){

          whle(true){
          }
    }

    因为如果是后者,将会导致同一时刻只能执行一个死循环,言外之意也就是说会导致另一个死循环停止执行,不再是所谓的死循环。两个线程也仅仅只会留下一个。

  • 相关阅读:
    VS Studio中复制窗体产生obj\Debug\SXP227\newform2.resources”在“Resources”参数中指定了多次。“Resources”参数不支持重复项 错误解决方案
    标签 frameset, frame ,noframes,iframe
    Winform GridView的允许自动生成列属性 AutoGenerateColumns
    目前自己的.Net的水平状态评估、方向
    C# 读取Excel中的时间
    asp.net中Button控件的单击回传机制
    javascript实现两个asp.net服务器控件ListBox值的互传
    关键字partial
    解决jQuery插件tipswindown与hintbox冲突
    C#数据结构三:单链表Singly Linked List
  • 原文地址:https://www.cnblogs.com/viplanyue/p/12700524.html
Copyright © 2020-2023  润新知