zoukankan      html  css  js  c++  java
  • Object中线程阻塞及唤醒方法的使用

    Object中线程阻塞及唤醒方法使用

    相关方法

    挂起: wait()/wait(long timeout)/wait(long timeout, int nanos)

    唤醒: notify()/notifyAll()

    使用说明

    • 调用对象的这些方法(wait/notify),必须先持有对象的监视器(monitor);否则会抛出IllegalMonitorStateException异常

      例1:

      public static void main(String[] args) {
      	Thread th1 = new Thread(){
      		@Override
      		public void run() {
      			try {
      				this.wait();
      			} catch (InterruptedException e) {
      				e.printStackTrace();
      			}
      		}
      	};
      	
      	th1.start();
      }
      

      运行结果:

      Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
      
      	at java.lang.Object.wait(Native Method)
      
      	at java.lang.Object.wait(Object.java:503)
      
      	at com.falco.src.verify.ObjectVerification$1.run(ObjectVerification.java:11)
      
    • 当调用对象的wait方法后,线程处于阻塞状态,对应的监视器(monitor)也被释放,其他线程可以获得此监视器来唤醒该线程。当线程重新被唤醒时,它会再次获取该监视器(monitor),然后被唤醒

    唤醒方式

    调用wait方法后,线程处于阻塞状态。可以通过以下四种唤醒方式:

    1. 调用notify/notifyAll方法唤醒

      例二:

      public static void main(String[] args) {
      		final Object bt = new Object();
      		Thread th1 = new Thread() {
      			@Override
      			public void run() {
      				try {
      					synchronized (bt) {
      						bt.wait();
      						System.out.println("the thread has been woke up.");
      					}
      				} catch (InterruptedException e) {
      					System.out.println("the current thread has been interupted.");
      					e.printStackTrace();
      				}
      			}
      		};
      		th1.start();
      	
      		Thread th2 = new Thread() {
      			@Override
      			public void run() {
      				synchronized (bt) {
      					bt.notify();
      					System.out.println("finish waking up.");
      				}
      			}
      		};
      		th2.start();
      		System.out.println("wait the program exit.");
      	}
      

      结果:

      wait the program exit.
      finish waking up.
      the thread has been woke up.
      
    2. 超时自动唤醒,即:wait方法指定一个超时时间,达到这个超时时间且没有被唤醒的线程将自动唤醒

      例三:

      	public static void main(String[] args) {
      		final Object bt = new Object();
      		Thread th1 = new Thread() {
      			@Override
      			public void run() {
      				try {
      					synchronized (bt) {
      						bt.wait(10,1);
      						System.out.println("the thread has been woke up.");
      					}
      				} catch (InterruptedException e) {
      					System.out.println("the current thread has been interupted.");
      					e.printStackTrace();
      				}
      			}
      		};
      		th1.start();
      		System.out.println("wait the program exit.");
      	}
      

      运行结果:

      wait the program exit.
      the thread has been woke up.
      
    3. 中断唤醒,在其他线程中,调用阻塞线程的中断方法,从而唤醒阻塞的线程

      例四:

      public static void main(String[] args) {
      		Thread th1 = new Thread() {
      			@Override
      			public void run() {
      				try {
      					synchronized (this) {
      						this.wait();
      					}
      				} catch (InterruptedException e) {
      					System.out.println("the current thread has been interupted.");
      					e.printStackTrace();
      				}
      			}
      		};
      
      		th1.start();
      		System.out.println("before interrupting,the interrupt flag:"+th1.isInterrupted());
      		th1.interrupt();
      		System.out.println("after interrupting,the interrupt flag:"+th1.isInterrupted());
      	}
      

      运行结果:

      before interrupting,the interrupt flag:false
      after interrupting,the interrupt flag:true
      the current thread has been interupted.
      java.lang.InterruptedException
      	at java.lang.Object.wait(Native Method)
      	at java.lang.Object.wait(Object.java:503)
      	at com.falco.src.verify.ObjectVerification$1.run(ObjectVerification.java:11)
      
    4. 假醒(spurious wakeup),除了以上三种方式外,处于阻塞中的线程还可能自动被唤醒

      由于假醒的存在,因此需要自行处理假醒的场景,通过下面的形式排出假醒,避免程序出错

      ...
      synchronized (bt) {
          while (condition) {//condition为不满足唤醒条件,即不满足唤醒条件时执行循环
          	bt.wait();
          }
      }
      ...
      

      假醒相关内容就不在这里介绍了,如果有兴趣,请自行研究

      假醒wiki地址

  • 相关阅读:
    lambba表达式
    根据某个字段筛选list数据
    git和idea绑定
    gitee创建仓库
    用 Python 3 + PyQt5 擼了一個可以播放“任意”音樂的播放器
    zabbix 共享内存设置
    Zabbix高可用,实现zabbix的无缝切换,无故障时间
    python练习题100
    斐波那契数列python实现
    随机生成指定位数密码包括大小写数字特殊符号
  • 原文地址:https://www.cnblogs.com/falco/p/9382715.html
Copyright © 2011-2022 走看看