• wait()和notify()


    从https://www.cnblogs.com/toov5/p/9837373.html 可以看到他的打印是一片一片的,这边博客介绍怎么避免掉

    使用notify 和 wait的时候 要注意 是在synchronize进行的,持有同一把锁

    1.因为涉及到对象锁,他们必须都放在synchronized中来使用. Wait、Notify一定要在synchronized里面进行使用。

    2.Wait必须暂定当前正在执行的线程,并释放资源锁,让其他线程可以有机会运行

    3. notify/notifyall: 唤醒因锁池中的线程,使之运行

    注意:一定要在线程同步中使用,并且是同一个锁的资源

    一片的原因是: cpu在调度时候 读一直被调度上了

    package com.toov5.thread;
    
    //共享对象
    class Res{
        public boolean flag = true;
        public String sex;
        public String name;
        
    }
    
    class inputThread extends Thread{
         public Res res;
         public inputThread(Res res) {
            this.res=res;
        }
        @Override
        public  void run() {
          int count=0; 
          while (true) {
              synchronized (res) {
                   if (res.flag) {
                  try {
                    res.wait();   //此处一定要用res的wait!!!! 执行到这里就会阻塞了 下面的代码不会执行了  释放当前锁对象
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                }
                    if (count==0) {
                        res.name="lucy";
                        res.sex="girl";    
                    }else {
                        res.name="Jack";
                        res.sex="boy";
                    }
                    count =(count+1)%2;
                    res.flag=true;  //写完了 标记当前线程为等待 然后走wait()了
                    res.notify();  //通知读的线程
            }
        }
        }
    }
    
    class readThread extends Thread{
        public Res res;
        public readThread(Res res) {
            this.res=res;
        }
        
        @Override
        public void run() {
            while (true) {    
            synchronized (res) {
                   if(!res.flag){
                     try {
                        res.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }    
                   }
                   System.out.println(res.name+","+res.sex);
                   //读完了时候要 
                   res.flag=false;
                   res.notify();//通知写的线程
                   
                }
            }        
        }
    }
    
    public class ConmunicatThreadTest {
        //开启两个线程  下面的线程 主线程 还有这俩用户线程 cpu随机的
    
        public static void main(String[] args) {
            Res res = new Res();
        inputThread inputThread = new inputThread(res);
        readThread  readThread = new readThread(res);
        inputThread.start();
        readThread.start();
        
        }  
           
        
    }

    看下结果:

    分析下: 

    两个线程 并行在执行 假设 flag为false  读的线程会等待  cpu执行权让给写的线程同时锁也会释放掉  

                                             写的时候 读的线程发现为true (while(true)的情况) 等待notify() 被唤醒,被唤醒后 从wait处继续往下执行  唤醒被等待的线程~~~

     notifyall 是唤醒所有的  小伙伴们可以自己试试哈

     注意  notify 和 wait 一定要在synchronize里面使用!!!!!并且同一个锁对象的!  

    wait与join 区别:

     wait需要唤醒  wait需要用在同步里面

    wait与sleep区别

    对于sleep()方法,我们首先要知道该方法是属于Thread类中的。而wait()方法,则是属于Object类中的。

    sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。

    在调用sleep()方法的过程中,线程不会释放对象锁。

    而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备

    获取对象锁进入运行状态。

      sleep不去释放锁 wait释放

    wait notify 为啥设计在object类 因为任意对象作为锁嘛 Object是任何类的祖宗~ 所以小伙伴们都明了了吧~~

  • 相关阅读:
    三地气温的典型相关分析
    android 使用 BroadcastReceiver 总结
    发布网站问题笔记
    Android 两个Activity 实现数据的来回传递
    input 标签屏蔽谷歌浏览器高亮显示
    javascript 获取当前html 标签的位置
    c# 四舍五入
    利用SQL的charindex实现字符串数组和Split函数
    ExtJs 一些常用的控件
    C#中return、break、continue的用法
  • 原文地址:https://www.cnblogs.com/toov5/p/9838143.html
Copyright © 2020-2023  润新知