zoukankan      html  css  js  c++  java
  • sleep与wait方法

    1.wait 属性Object类 

    (1)首先,调用了wait()之后会引起当前线程处于等待状状态。

    (2)其次,每个线程必须持有该对象的monitor。如果在当前线程中调用wait()方法之后,该线程就会释放monitor的持有对象并让自己处于等待状态。

    (3)如果想唤醒一个正在等待的线程,那么需要开启一个线程通过notify()或者notifyAll()方法去通知正在等待的线程获取monitor对象。如此,该线程即可打破等待的状态继续执行代码。

    sleep属于 Thread 类

    (1)首先,调用sleep()之后,会引起当前执行的线程进入暂时中断状态,也即睡眠状态。

    (2)其次,虽然当前线程进入了睡眠状态,但是依然持有monitor对象。

    (3)在中断完成之后,自动进入唤醒状态从而继续执行代码。

    2 .首先写个demo  来看

    public class SleepTest {

    public static void main(String[] args) {
    ThreadOne one = new ThreadOne();
    ThreadTwo two = new ThreadTwo();
    one.start();
    two.start();
    }

    }class ThreadOne extends Thread{

    public void run(){
     

    System.out.println("进入了sleep方法当前时间是"+new Date().toLocaleString());
    sleep(1000);
    System.out.println("sleep方法结束当前时间是"+new Date().toLocaleString());

    } catch ( 

    class ThreadTwo extends Thread{
    public void run(){
    try {
    wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }

    }

    运行结果:

    进入了sleep方法当前时间是2018-7-26 11:24:50
    sleep方法结束当前时间是2018-7-26 11:24:51

    Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:485)
    at com.zz.www.Thread.ThreadTwo.run(SleepTest.java:30)

    可以看出  sleep方法用法比较简单  但是 wait 方法 必须在synchronized 方法内使用;

    修改一下ThreadTwo 

    class ThreadTwo extends Thread{

    public void run(){
    gogo();
    }

    public synchronized void gogo(){
    try {
    System.out.println("进入了wait方法 当前时间是"+new Date().toLocaleString());
    this.wait(10000);//当前线程等待10000毫秒
    System.out.println("wait方法结束 当前时间是"+new Date().toLocaleString());
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }

    再次运行结果为

    进入了wait方法 当前时间是2018-7-26 11:25:50
    进入了sleep方法当前时间是2018-7-26 11:25:50
    sleep方法结束当前时间是2018-7-26 11:25:51
    wait方法结束 当前时间是2018-7-26 11:26:00

    3.  notify(), notifyAll(),wait(), wait(long), wait(long, int)操作,都需要锁对象

    例如 :
    exapmle 1,锁定方法所属的实例对象:
    public synchronized void method(){
        //然后就可以调用:this.notify()...
        //或者直接调用notify()...
    }
    exapmle 2,锁定方法所属的实例的Class:
    public Class Test{
     public static synchronized void method(){
        //然后调用:Test.class.notify()...
     }
    }
    exapmle 3,锁定其他对象:
    public Class Test{
    public Object lock = new Object();
     public static void method(){
        synchronized (lock) {
         //需要调用 lock.notify();
        } 
     }
    }

     4 测试 wait  与 notify 

    public class SleepTest {
    private final static Object obj = new Object();
    public static void main(String[] args) {
    // ThreadOne one = new ThreadOne();
    // ThreadTwo two = new ThreadTwo();
    // one.start();
    // two.start();

    Thread thread = new Thread(new Runnable() {
    public void run() {
    synchronized (obj) {
    try {
    System.out.println("进入了wait方法 当前时间是"+ new Date().toLocaleString());
    obj.wait();
    System.out.println("wait方法结束 当前时间是"+ new Date().toLocaleString());
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    });
    thread.start();

    Thread tha = new Thread(new Runnable() {
    public void run() {
    synchronized (obj) {
    obj.notify();
    }
    }
    });
    tha.start();
    }
    }

    运行结果:

    进入了wait方法 当前时间是2018-7-26 14:32:41
    wait方法结束 当前时间是2018-7-26 14:32:41

    notify()方法
    (1)当一个线程处于wait()状态时,也即等待它之前所持有的object's monitor被释放,通过notify()方法可以让该线程重新处于活动状态,从而去抢夺object's monitor,唤醒该线程。
    (2)如果多个线程同时处于等待状态,那么调用notify()方法只能随机唤醒一个线程。
    (3)在同一时间内,只有一个线程能够获得object's monitor,执行完毕之后,则再将其释放供其它线程抢占。
     
    notifyAll()就是用来唤醒正在等待状态中的所有线程
    (1)notifyAll()只会唤醒那些等待抢占指定object's monitor的线程,其他线程则不会被唤醒。
    (2)notifyAll()只会一个一个的唤醒,而并非统一唤醒。因为在同一时间内,只有一个线程能够持有object's monitor
    (3)notifyAll()只是随机的唤醒线程,并非有序唤醒。
    那么如何做到有序唤醒是我们接下来要讨论的问题。
  • 相关阅读:
    第二章 Java浮点数精确计算
    第一章 Java代码执行流程
    第九章 JVM调优推荐
    第八章 JVM性能监控与故障处理工具(2)
    基于Redis构建10万+终端级的高性能部标JT808协议的Gps网关服务器(转)
    基于Java Netty框架构建高性能的Jt808协议的GPS服务器(转)
    Netty(七):流数据的传输处理
    Java中的位运算符
    二进制(原码、反码、补码)
    Java数据结构和算法(二):数组
  • 原文地址:https://www.cnblogs.com/zjf6666/p/9370915.html
Copyright © 2011-2022 走看看